-
Notifications
You must be signed in to change notification settings - Fork 538
[TOOL-4621] New ERC20 public contract page #7177
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
[TOOL-4621] New ERC20 public contract page #7177
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
WalkthroughThis update introduces a new ERC20 public contract page with a dedicated UI, charting, recent transfer display, and buy functionality. It adds new hooks, components, and conditional logic to render this page when appropriate, while redirecting away from legacy contract subpages. Several layout components are updated to include a consistent team header. Environment variable usage is standardized throughout the codebase. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant SharedContractOverviewPage
participant shouldRenderNewPublicPage
participant RenderNewPublicContractPage
participant ERC20PublicPage
User->>SharedContractOverviewPage: Request contract overview (no projectMeta)
SharedContractOverviewPage->>shouldRenderNewPublicPage: Check contract type
shouldRenderNewPublicPage-->>SharedContractOverviewPage: Return { type: "erc20" } or false
alt ERC20 contract
SharedContractOverviewPage->>RenderNewPublicContractPage: Render with type "erc20"
RenderNewPublicContractPage->>ERC20PublicPage: Render ERC20 public UI
else Not ERC20
SharedContractOverviewPage->>DefaultOverview: Render legacy overview
end
sequenceDiagram
participant User
participant LegacySubpage
participant shouldRenderNewPublicPage
participant redirectToContractLandingPage
User->>LegacySubpage: Request legacy subpage (no projectMeta)
LegacySubpage->>shouldRenderNewPublicPage: Check contract type
shouldRenderNewPublicPage-->>LegacySubpage: Return { type: "erc20" } or false
alt ERC20 contract
LegacySubpage->>redirectToContractLandingPage: Redirect to ERC20 public page
else Not ERC20
LegacySubpage->>LegacySubpage: Render legacy subpage
end
Assessment against linked issues
Possibly related PRs
Suggested labels
Suggested reviewers
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (2)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #7177 +/- ##
=======================================
Coverage 55.62% 55.62%
=======================================
Files 908 908
Lines 58531 58531
Branches 4128 4128
=======================================
Hits 32556 32556
Misses 25869 25869
Partials 106 106
🚀 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: 9
♻️ Duplicate comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx (1)
30-40
: Logic is correct but follows the same duplication pattern.The conditional logic correctly prevents the tokens page from being displayed for new public pages when
projectMeta
is undefined. The comment clearly explains the purpose.This follows the same code duplication pattern noted in the events page review. Consider the same refactoring suggestion to extract this common logic.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (1)
26-36
: Well-integrated conditional logic that fits with existing patterns.The new conditional redirect logic is correctly implemented and integrates well with the existing redirect logic already present in this file (lines 57-62). The logic appropriately prevents the claim conditions page from being displayed for new public pages.
This also follows the same code duplication pattern noted in previous files. The same refactoring suggestion applies here.
🧹 Nitpick comments (19)
apps/dashboard/src/data/analytics/contract-event-breakdown.ts (1)
2-2
: Consider using absolute import alias
The import currently uses a relative path; for consistency with other modules (e.g.,@/constants/public-envs
), consider switching to an absolute alias:-import { NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID } from "../../@/constants/public-envs"; +import { NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID } from "@/constants/public-envs";apps/dashboard/src/app/(app)/(dashboard)/support/layout.tsx (1)
1-16
: Consider extracting a shared layout component to reduce duplication.The implementation is correct and consistent with other dashboard layouts. However, this code is identical to several other layout files in the PR. Consider creating a shared
DashboardSectionLayout
component to reduce code duplication.Example shared component:
// components/layouts/DashboardSectionLayout.tsx import { TeamHeader } from "../../team/components/TeamHeader/team-header"; export function DashboardSectionLayout({ children, }: { children: React.ReactNode; }) { return ( <div className="flex grow flex-col"> <div className="border-border border-b bg-card"> <TeamHeader /> </div> {children} </div> ); }apps/dashboard/src/app/(app)/(dashboard)/explore/layout.tsx (1)
1-16
: LGTM! Consistent with the dashboard layout pattern.The implementation correctly follows the established pattern for dashboard section layouts. The code is clean and properly structured.
This is another instance of the identical layout pattern. Consider the shared component approach mentioned in the support layout review to reduce duplication across all these similar layout files.
apps/dashboard/src/app/(app)/(dashboard)/profile/layout.tsx (1)
1-16
: Consider extracting a shared layout component to reduce duplication.This layout is identical to
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/tx/layout.tsx
. Consider creating a sharedDashboardLayoutWithTeamHeader
component to follow DRY principles and improve maintainability.Would you like me to help create a shared layout component that both files can use?
// Create apps/dashboard/src/components/layouts/DashboardLayoutWithTeamHeader.tsx +import { TeamHeader } from "../../app/(app)/team/components/TeamHeader/team-header"; + +export function DashboardLayoutWithTeamHeader({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <div className="flex grow flex-col"> + <div className="border-border border-b bg-card"> + <TeamHeader /> + </div> + {children} + </div> + ); +} // Then update this file: -import { TeamHeader } from "../../team/components/TeamHeader/team-header"; +import { DashboardLayoutWithTeamHeader } from "../../../components/layouts/DashboardLayoutWithTeamHeader"; export default function Layout({ children, }: { children: React.ReactNode; }) { - return ( - <div className="flex grow flex-col"> - <div className="border-border border-b bg-card"> - <TeamHeader /> - </div> - {children} - </div> - ); + return <DashboardLayoutWithTeamHeader>{children}</DashboardLayoutWithTeamHeader>; }apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx (1)
23-33
: Consider extracting the repeated conditional logic into a reusable helper.The conditional logic is correct and prevents the events page from being displayed for new public pages. However, this exact pattern appears to be repeated across multiple shared page files.
Consider creating a higher-order component or utility function to reduce code duplication:
async function checkAndRedirectForNewPublicPage( params: { projectMeta: ProjectMeta | undefined; serverContract: ThirdwebContract; contractAddress: string; chainIdOrSlug: string; } ): Promise<boolean> { if (!params.projectMeta) { const shouldHide = await shouldRenderNewPublicPage(params.serverContract); if (shouldHide) { redirectToContractLandingPage({ contractAddress: params.contractAddress, chainIdOrSlug: params.chainIdOrSlug, projectMeta: params.projectMeta, }); } } return false; }apps/dashboard/src/app/(app)/(dashboard)/(chain)/chainlist/layout.tsx (1)
1-16
: LGTM! Consistent layout pattern implementation.The layout component correctly implements the same pattern as other dashboard sections. The import path is appropriately adjusted for the directory structure.
Consider extracting a shared layout component if this exact pattern is used across many sections to reduce code duplication.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1)
26-36
: Consider adding error handling for the async operation.The conditional logic correctly implements the redirect pattern for new public pages. However, the
shouldRenderNewPublicPage
call could potentially throw an error that's not being handled.Consider wrapping the async operation in a try-catch block:
// new public page can't show /permissions page if (!props.projectMeta) { - const shouldHide = await shouldRenderNewPublicPage(info.serverContract); - if (shouldHide) { - redirectToContractLandingPage({ - contractAddress: props.contractAddress, - chainIdOrSlug: props.chainIdOrSlug, - projectMeta: props.projectMeta, - }); - } + try { + const shouldHide = await shouldRenderNewPublicPage(info.serverContract); + if (shouldHide) { + redirectToContractLandingPage({ + contractAddress: props.contractAddress, + chainIdOrSlug: props.chainIdOrSlug, + projectMeta: props.projectMeta, + }); + } + } catch (error) { + console.warn('Failed to check if contract should render new public page:', error); + // Continue with normal flow + } }apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PayEmbedSection.tsx (1)
18-18
: Consider extracting CSS classes to a constant.For better maintainability, consider extracting the Tailwind classes to a constant or using a more semantic approach.
+ const embedStyles = "!rounded-xl !w-full"; + return ( <PayEmbed - className="!rounded-xl !w-full" + className={embedStyles} client={props.client}apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
10-12
: Consider logging the error for debugging purposes.While the current error handling silently continues, it might be helpful to log errors for debugging purposes in development environments.
const functionSelectors = await resolveFunctionSelectors(contract).catch( - () => undefined, + (error) => { + if (process.env.NODE_ENV === 'development') { + console.warn('Failed to resolve function selectors:', error); + } + return undefined; + }, );apps/dashboard/src/components/analytics/empty-chart-state.tsx (1)
74-81
: Consider extracting gradient definition to improve reusability.The linear gradient definition is well-implemented but could be extracted for potential reuse across other area charts in the system.
Consider defining the gradient in a shared constants file or as a reusable component:
// In a shared constants file export const AREA_CHART_GRADIENTS = { skeleton: "fill_area_skeleton", // other gradients... } as const;This would improve maintainability if similar gradients are used elsewhere.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts (1)
5-17
: Add documentation for the TokenTransfersData type.The type definition is comprehensive but would benefit from JSDoc comments explaining the purpose and structure of each field.
+/** + * Represents a token transfer event with metadata + */ export type TokenTransfersData = { + /** Source wallet address */ from_address: string; + /** Destination wallet address */ to_address: string; + /** Contract address of the token */ contract_address: string; // ... add documentation for other fields };apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx (3)
51-78
: Consider consolidating number formatters.Multiple
Intl.NumberFormat
instances are defined with similar configurations. Consider creating a utility module to centralize these formatters for reusability and maintainability.Consider creating a
formatters.ts
utility file:export const formatters = { usdCurrency: new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 4, roundingMode: "halfEven", notation: "compact", }), marketCap: new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0, roundingMode: "halfEven", notation: "compact", }), // ... other formatters };
102-125
: Simplify the date filtering logic.The filtering logic can be simplified using a lookup map for better readability and maintainability.
+const INTERVAL_DAYS: Record<Interval, number> = { + "24h": 1, + "7d": 7, + "30d": 30, + "1y": 365, + "max": Infinity, +}; const filteredHistoricalPrices = useMemo(() => { const currentDate = new Date(); if (tokenPriceData?.type === "no-data") { return []; } return tokenPriceData?.data?.historical_prices.filter((item) => { const date = new Date(item.date); - const maxDiff = - interval === "24h" - ? 1 - : interval === "7d" - ? 7 - : interval === "30d" - ? 30 - : 365; + const maxDiff = INTERVAL_DAYS[interval]; - if (differenceInCalendarDays(currentDate, date) <= maxDiff) { - return true; - } - return false; + return differenceInCalendarDays(currentDate, date) <= maxDiff; }); }, [tokenPriceData, interval]);
93-245
: Consider breaking down the large TokenStats component.The
TokenStats
component is handling multiple responsibilities (data fetching, filtering, rendering). Consider splitting it into smaller, focused components for better maintainability.Consider extracting sub-components like:
TokenPriceDisplay
for current price and change displayTokenMetricsGrid
for market cap and holdersTokenStatsContainer
as the main orchestratorapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx (2)
18-20
: Make chain name cleaning more robust.The current string manipulation only handles "Mainnet" removal. Consider a more flexible approach for different chain naming patterns.
-const cleanedChainName = props.chainMetadata?.name - ?.replace("Mainnet", "") - .trim(); +const cleanedChainName = props.chainMetadata?.name + ?.replace(/\s*(Mainnet|Testnet|Network)\s*/gi, "") + .trim();
86-86
: Address the TODO comment.The TODO comment indicates planned functionality for social links. Consider creating a follow-up task or implementing this feature.
Would you like me to help implement the social links functionality or create an issue to track this feature?
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts (1)
44-46
: Enhance error handling with more context.The current error handling only includes the response text. Consider adding more context for debugging.
if (!res.ok) { - throw new Error(await res.text()); + const errorText = await res.text(); + throw new Error(`Failed to fetch token price data (${res.status}): ${errorText}`); }apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx (2)
81-86
: Simplify the table row key generation.The current key generation is overly complex and could be simplified while maintaining uniqueness.
key={ - transfer.transaction_hash + - transfer.amount + - transfer.block_number + - transfer.from_address + `${transfer.transaction_hash}-${transfer.log_index}` }The combination of
transaction_hash
andlog_index
should provide sufficient uniqueness while being more concise.
162-162
: Improve pagination logic for better UX.The current logic disables the "Next" button when data length is 0, but it should also consider if there might be more data available (e.g., when data.length < rowsPerPage).
disabled={props.isPending || props.data.length === 0} +disabled={props.isPending || props.data.length < props.rowsPerPage}
This assumes that if fewer items than
rowsPerPage
are returned, there are no more pages available.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (54)
apps/dashboard/src/@/actions/getWalletNFTs.ts
(2 hunks)apps/dashboard/src/@/components/blocks/charts/area-chart.tsx
(4 hunks)apps/dashboard/src/@/components/blocks/charts/bar-chart.tsx
(1 hunks)apps/dashboard/src/@/components/ui/LoadingDots.tsx
(1 hunks)apps/dashboard/src/@/constants/public-envs.ts
(1 hunks)apps/dashboard/src/@/constants/thirdweb.server.ts
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(bridge)/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx
(3 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/metadata-header.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-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/PublicPageConnectButton.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PayEmbedSection.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx
(5 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx
(4 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/tx/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/chainlist/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/contracts/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/explore/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/layout.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/profile/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/published-contract/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/support/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/tools/layout.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/components/Analytics/BarChart.tsx
(1 hunks)apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx
(1 hunks)apps/dashboard/src/app/pay/constants.ts
(2 hunks)apps/dashboard/src/components/analytics/empty-chart-state.tsx
(2 hunks)apps/dashboard/src/data/analytics/contract-event-breakdown.ts
(2 hunks)apps/dashboard/src/data/analytics/contract-events.ts
(2 hunks)apps/dashboard/src/data/analytics/contract-function-breakdown.ts
(2 hunks)apps/dashboard/src/data/analytics/contract-transactions.ts
(2 hunks)apps/dashboard/src/data/analytics/contract-wallet-analytics.ts
(2 hunks)apps/dashboard/src/data/analytics/total-contract-events.ts
(2 hunks)apps/dashboard/src/data/analytics/total-contract-transactions.ts
(2 hunks)apps/dashboard/src/data/analytics/total-unique-wallets.ts
(2 hunks)
💤 Files with no reviewable changes (1)
- apps/dashboard/src/app/(app)/(dashboard)/layout.tsx
🧰 Additional context used
🧠 Learnings (4)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1)
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx:47-52
Timestamp: 2025-05-26T16:29:54.317Z
Learning: The `projectMeta` prop is not required for the server-rendered `ContractDirectListingsPage` component in the direct listings shared page, following the same pattern as other server components in the codebase where `projectMeta` is only needed for client components.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx (1)
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx:43-49
Timestamp: 2025-05-26T16:31:02.480Z
Learning: In the thirdweb dashboard codebase, when `redirectToContractLandingPage()` is called, an explicit return statement is not required afterward because the function internally calls Next.js's `redirect()` which throws an error to halt execution.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx (1)
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx:41-48
Timestamp: 2025-05-26T16:28:50.772Z
Learning: The `projectMeta` prop is not required for the server-rendered `ContractTokensPage` component in the tokens shared page, unlike some other shared pages where it's needed for consistency.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (1)
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx:41-48
Timestamp: 2025-05-26T16:28:50.772Z
Learning: The `projectMeta` prop is not required for the server-rendered `ContractTokensPage` component in the tokens shared page, unlike some other shared pages where it's needed for consistency.
🧬 Code Graph Analysis (35)
apps/dashboard/src/app/(app)/team/components/Analytics/BarChart.tsx (1)
apps/dashboard/src/components/analytics/empty-chart-state.tsx (1)
EmptyChartState
(24-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/metadata-header.tsx (2)
apps/dashboard/src/components/icons/ChainIcon.tsx (1)
ChainIconClient
(17-37)packages/engine/src/client/client.gen.ts (1)
client
(24-28)
apps/dashboard/src/data/analytics/contract-transactions.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/data/analytics/total-contract-events.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/data/analytics/total-unique-wallets.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/@/constants/thirdweb.server.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/@/actions/getWalletNFTs.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/data/analytics/contract-wallet-analytics.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/data/analytics/contract-event-breakdown.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx (1)
apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx (1)
TeamHeader
(14-59)
apps/dashboard/src/data/analytics/contract-events.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/app/(app)/(dashboard)/explore/layout.tsx (1)
apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx (1)
TeamHeader
(14-59)
apps/dashboard/src/data/analytics/total-contract-transactions.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
shouldRenderNewPublicPage
(7-27)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts (1)
redirectToContractLandingPage
(6-18)
apps/dashboard/src/@/components/blocks/charts/bar-chart.tsx (1)
apps/dashboard/src/components/analytics/empty-chart-state.tsx (1)
EmptyChartState
(24-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
shouldRenderNewPublicPage
(7-27)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts (1)
redirectToContractLandingPage
(6-18)
apps/dashboard/src/app/(app)/(dashboard)/support/layout.tsx (1)
apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx (1)
TeamHeader
(14-59)
apps/dashboard/src/data/analytics/contract-function-breakdown.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/app/pay/constants.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/tx/layout.tsx (1)
apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx (1)
TeamHeader
(14-59)
apps/dashboard/src/app/(app)/(dashboard)/contracts/layout.tsx (1)
apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx (1)
TeamHeader
(14-59)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
shouldRenderNewPublicPage
(7-27)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts (1)
redirectToContractLandingPage
(6-18)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (6)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx (1)
ContractPageLayoutClient
(14-54)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
shouldRenderNewPublicPage
(7-27)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx (1)
ContractPageLayout
(13-72)apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChat.tsx (1)
NebulaChatButton
(27-110)apps/dashboard/src/app/nebula-app/(app)/data/examplePrompts.ts (1)
examplePrompts
(83-108)apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx (1)
TeamHeader
(14-59)
apps/dashboard/src/app/(app)/(dashboard)/profile/layout.tsx (1)
apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx (1)
TeamHeader
(14-59)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
shouldRenderNewPublicPage
(7-27)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts (1)
redirectToContractLandingPage
(6-18)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (6)
packages/thirdweb/src/exports/thirdweb.ts (1)
ThirdwebContract
(71-71)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx (1)
PageHeader
(6-26)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx (1)
ContractHeaderUI
(11-91)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx (1)
TokenStats
(93-245)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PayEmbedSection.tsx (1)
BuyTokenEmbed
(8-46)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx (1)
RecentTransfers
(196-246)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/chainlist/layout.tsx (1)
apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx (1)
TeamHeader
(14-59)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts (2)
apps/dashboard/src/@/constants/env-utils.ts (1)
isProd
(1-3)apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/components/analytics/empty-chart-state.tsx (2)
apps/dashboard/src/@/components/ui/LoadingDots.tsx (1)
LoadingDots
(1-10)apps/dashboard/src/app/(app)/team/components/Analytics/BarChart.tsx (1)
BarChart
(19-108)
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/layout.tsx (1)
apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx (1)
TeamHeader
(14-59)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts (2)
apps/dashboard/src/@/constants/env-utils.ts (1)
isProd
(1-3)apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
apps/dashboard/src/@/components/blocks/charts/area-chart.tsx (2)
apps/dashboard/src/@/components/ui/chart.tsx (1)
ChartContainer
(370-370)apps/dashboard/src/components/analytics/empty-chart-state.tsx (2)
LoadingChartState
(40-46)EmptyChartState
(24-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx (4)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts (2)
TokenTransfersData
(5-17)useTokenTransfers
(19-56)apps/dashboard/src/@/components/blocks/wallet-address.tsx (1)
WalletAddress
(22-167)apps/dashboard/src/@/components/ui/button.tsx (1)
Button
(67-67)packages/thirdweb/src/exports/thirdweb.ts (1)
ThirdwebContract
(71-71)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (2)
packages/thirdweb/src/exports/thirdweb.ts (1)
createThirdwebClient
(24-24)apps/dashboard/src/@/constants/public-envs.ts (1)
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
(1-2)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: Unit Tests
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: Build Packages
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Lint Packages
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Size
- GitHub Check: Analyze (javascript)
🔇 Additional comments (73)
apps/dashboard/src/@/components/ui/LoadingDots.tsx (1)
1-10
: Excellent implementation with great accessibility!The
LoadingDots
component is well-implemented with:
- Proper accessibility support via
sr-only
text for screen readers- Smooth staggered animation using CSS animation delays
- Clean, semantic JSX structure
- Appropriate use of Tailwind CSS classes
The bouncing animation with different delays (
-0.3s
,-0.15s
,0s
) creates a visually appealing wave effect.apps/dashboard/src/app/(app)/team/components/Analytics/BarChart.tsx (1)
45-45
: Correct implementation of the updated EmptyChartState API.The addition of
type="bar"
prop correctly implements the updatedEmptyChartState
component API requirements as shown in the relevant code snippets fromapps/dashboard/src/components/analytics/empty-chart-state.tsx
. This ensures proper skeleton chart rendering for bar chart empty states.apps/dashboard/src/app/pay/constants.ts (2)
2-2
: Import statement correctly updated.The import statement has been properly updated to use the corrected constant name
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
, maintaining consistency with the changes made in the constants file.
36-36
: Usage correctly updated to match the import.The client ID usage has been properly updated to use the corrected constant name, ensuring consistency throughout the file.
Note: This change depends on the naming consistency issue flagged in
apps/dashboard/src/@/constants/public-envs.ts
where the constant name doesn't match the environment variable name.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx (2)
7-7
: Correct environment variable import
Updated the import to use the correctly namedNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
, aligning with the constant defined inpublic-envs.ts
.
16-18
: Update placeholder replacement to use the new client ID
Replaces the${THIRDWEB_API_KEY}
placeholder withNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
to ensure RPC calls include the proper key.apps/dashboard/src/data/analytics/contract-transactions.ts (2)
1-1
: Align client ID import
Switched to importNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
frompublic-envs
, matching the standardized environment variable name.
52-52
: Use updated client ID in headers
Ensures the"x-client-id"
header references the renamed constant for analytics requests.apps/dashboard/src/data/analytics/total-contract-events.ts (2)
1-1
: Align client ID import
Imported the correctly namedNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
frompublic-envs
to standardize environment variable usage.
31-31
: Use updated client ID in request header
Replaced the old constant withNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
under the"x-client-id"
header for consistency.apps/dashboard/src/data/analytics/total-unique-wallets.ts (2)
1-1
: Align client ID import
Updated the import to useNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
, reflecting the renamed environment variable.
31-31
: Use updated client ID in headers
Ensures the analytics fetch includes the newNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
in the"x-client-id"
header.apps/dashboard/src/data/analytics/contract-event-breakdown.ts (1)
49-49
: Use updated client ID in headers
Replaced the old constant withNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
for the"x-client-id"
header, aligning with the renamed environment variable.apps/dashboard/src/data/analytics/contract-events.ts (1)
2-2
: LGTM! Typo correction for environment variable constant.The import and usage have been correctly updated from
NET_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
toNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
, fixing the typo in the prefix and aligning with the actual constant definition inpublic-envs.ts
.Also applies to: 52-52
apps/dashboard/src/data/analytics/contract-function-breakdown.ts (1)
2-2
: LGTM! Consistent typo correction for environment variable constant.The import and usage have been correctly updated from
NET_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
toNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
, maintaining consistency with the fix applied across other analytics files.Also applies to: 49-49
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1)
22-22
:✅ Verification successful
LGTM! Improved data integrity by using fetched project data.
Using
project.slug
instead ofparams.project_slug
ensures consistency with the actual project data from the database, which is more reliable than URL parameters.Please verify that the URL slug parameter and database slug are always consistent to ensure this change doesn't break existing functionality:
🏁 Script executed:
#!/bin/bash # Description: Check for any potential issues with project slug consistency # Expected: No hardcoded assumptions about slug differences # Search for other usages of project_slug parameter vs project.slug rg -A 3 -B 3 "params\.project_slug|project\.slug" --type tsLength of output: 65598
Direct-listings page slug usage verified
Verified that in
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx
theprojectSlug
prop now correctly usesproject.slug
. No breaking change in this file.Note: our search shows other pages (e.g. the English-auctions page) still pass
params.project_slug
. You may choose to standardize slug usage across all pages in a follow-up, but this PR’s change is safe as is.apps/dashboard/src/@/actions/getWalletNFTs.ts (1)
15-15
: LGTM! Completing the systematic typo correction.The import and usage have been correctly updated from
NET_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
toNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
, completing the systematic correction across the codebase and ensuring consistent client ID header usage.Also applies to: 152-152
apps/dashboard/src/data/analytics/total-contract-transactions.ts (1)
1-1
: LGTM! Environment variable name correction applied correctly.The import and usage have been consistently updated to use the correct
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
constant, aligning with Next.js environment variable naming conventions.Also applies to: 31-31
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (1)
8-8
: LGTM! Consistent environment variable standardization.The import and client initialization have been properly updated to use the corrected
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
constant, maintaining consistency across the codebase.Also applies to: 14-14
apps/dashboard/src/@/constants/thirdweb.server.ts (1)
2-2
: LGTM! Environment variable standardization completed correctly.The import and usage in the client configuration have been consistently updated to use the correct
NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
constant.Also applies to: 79-79
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/metadata-header.tsx (2)
116-116
: LGTM! Styling update improves consistency.The addition of padding classes
px-2.5 py-1.5
to the CopyAddressButton maintains visual consistency with other button elements in the component.
85-97
:✅ Verification successful
Verify that chain.slug is always defined before removing conditional guards.
The removal of conditional rendering around the Link component means it will always render and directly use
chain.slug
in the href. Ifchain.slug
could be undefined, this would result in a malformed URL (/undefined
).Please verify that
chain.slug
is guaranteed to be defined for all ChainMetadata instances used in this component:
🏁 Script executed:
#!/bin/bash # Description: Check ChainMetadata type definition and usage to verify slug is always defined # Expected: Find type definition and confirm slug property is required # Search for ChainMetadata type definition ast-grep --pattern $'type ChainMetadata = { $$$ slug$_ $$$ }' # Also search for interface definition ast-grep --pattern $'interface ChainMetadata { $$$ slug$_ $$$ }' # Search for any optional slug properties rg -A 3 -B 3 "slug\?"Length of output: 6387
🏁 Script executed:
#!/bin/bash # Locate the metadata-header file and print its imports and prop types file=$(fd metadata-header.tsx apps/dashboard) echo "Inspecting: $file" sed -n '1,200p' "$file"Length of output: 4821
🌐 Web query:
Does the ChainMetadata interface in the thirdweb/chains TypeScript SDK define the `slug` property as required or optional?
💡 Result:
Based on the search results, the
slug
property in the ChainMetadata interface in the thirdweb TypeScript SDK is defined as required, not optional.Looking at the return type definition from the
getChainMetadata
function, we can see that theslug
property is listed without a question mark, indicating it is a required property[5]. In TypeScript, optional properties are typically denoted with a question mark after the property name.The return type includes:
{ // other properties slug: string; // other properties }This is further evidenced by the structure of the ChainMetadata interface shown in the documentation, where properties like
status
are marked with a question mark (status?
), indicating they are optional, whileslug
has no such marker[6].Additionally, when working with custom chains, the documentation emphasizes the importance of the
slug
property, as seen in the example for adding a custom chain where theslug
property is included in the chain definition[9]:{ "name": "My Custom Chain", "chain": "ETH", "rpc": ["https://my-custom-rpc-url.com"], "nativeCurrency": { "name": "Ether", "symbol": "ETH", "decimals": 18 }, "chainId": 678, "slug": "my-custom-chain" }The documentation also notes that "Chain slugs are only supported for public chains," which further suggests that the
slug
property is an essential part of the chain metadata structure[9].Citations:
- 1: https://portal.thirdweb.com/typescript/v5/chain
- 2: https://portal.thirdweb.com/references/typescript/v5/chains
- 3: https://portal.thirdweb.com/references/typescript/v5/useChainMetadata
- 4: https://docs.tenderly.co/node/integrations-dapp-ui/thirdweb-sdk
- 5: https://portal.thirdweb.com/typescript/v5/getChainMetadata
- 6: https://portal.thirdweb.com/references/typescript/v5/ChainMetadata
- 7: ThirdwebProvider doesn't support passing Base Goerli chainId or slug #1082
- 8: https://portal.thirdweb.com/references/typescript/v4/getChainMetadata
- 9: https://portal.thirdweb.com/engine/v2/features/custom-chains
No Guard Needed:
chain.slug
Is Always DefinedThe
ChainMetadata
interface in the thirdweb/chains SDK declaresslug: string
(no?
), so it’s a required property. Removing the conditional around the<Link>
is safe with respect tochain.slug
.apps/dashboard/src/data/analytics/contract-wallet-analytics.ts (1)
2-2
: LGTM! Environment variable name corrected.The import and usage have been correctly updated from
NET_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
toNEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID
, which follows Next.js environment variable conventions and aligns with the constant definition inapps/dashboard/src/@/constants/public-envs.ts
.Also applies to: 52-52
apps/dashboard/src/@/components/blocks/charts/bar-chart.tsx (1)
78-80
: LGTM! Proper chart type specification for empty state.The addition of
type="bar"
to theEmptyChartState
component ensures the empty state visualization matches the bar chart type. This aligns with the enhancedEmptyChartState
component that now supports different chart types ("bar"
|"area"
).apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (2)
23-23
: LGTM! Appropriate imports for new public page functionality.The imports for
redirectToContractLandingPage
andshouldRenderNewPublicPage
utilities are correctly added to support the new conditional redirect logic.Also applies to: 26-26
53-63
: LGTM! Well-structured conditional redirect logic.The implementation correctly handles the new public page scenario:
- Only executes when
projectMeta
is undefined (appropriate guard condition)- Uses
shouldRenderNewPublicPage
to determine if the contract should render a new public page variant- Redirects to the contract landing page when applicable
This follows a consistent pattern across the codebase and prevents the cross-chain page from rendering for new public page types.
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/layout.tsx (1)
1-16
: LGTM! Clean layout component with consistent TeamHeader integration.This layout component follows the established pattern across the dashboard application:
- Proper structure: Uses a flex column layout with the
TeamHeader
positioned at the top- Consistent styling: Applies consistent border and background styling for the header section
- Type safety: Correctly types the
children
prop asReact.ReactNode
- Pattern adherence: Aligns with similar layout components added across the dashboard sections
The integration with the
TeamHeader
component (which handles authentication and team management) is appropriate for this layout level.apps/dashboard/src/app/(app)/(dashboard)/published-contract/layout.tsx (1)
1-16
: LGTM! Clean and consistent layout implementation.The layout follows the established pattern for dashboard sections with proper flex styling and TeamHeader integration. The import path and component structure look correct.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx (2)
27-27
: LGTM! Proper import addition.The TeamHeader import is correctly added with the appropriate relative path.
99-102
: LGTM! Consistent header integration.The TeamHeader is properly integrated into the existing layout structure while preserving all existing functionality. The wrapper follows the same pattern established in other dashboard layouts.
Also applies to: 232-232
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/tx/layout.tsx (1)
1-16
: LGTM! Consistent layout implementation.The layout follows the established pattern seen across other dashboard sections with proper TeamHeader integration and consistent styling.
apps/dashboard/src/app/(app)/(dashboard)/tools/layout.tsx (2)
3-3
: LGTM! Proper TeamHeader import.The import path is correct for the file location.
15-45
: LGTM! Consistent TeamHeader integration.The layout properly wraps the existing SidebarLayout with TeamHeader while preserving all existing functionality and sidebar links. The structure follows the established pattern across other dashboard layouts.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (2)
6-6
: LGTM! Proper import addition.The import for
redirectToContractLandingPage
is correctly added.
9-9
: LGTM! Proper import addition.The import for
shouldRenderNewPublicPage
utility is correctly added.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx (2)
1-26
: LGTM! Clean and well-structured header component.The
PageHeader
component is well-implemented with proper separation of navigation and interactive elements. The responsive design appropriately hides the "thirdweb" text on smaller screens while maintaining the logo visibility.
11-11
: Verify the "/team" navigation path is correct.The header links to
/team
which seems to be the intended destination based on the context. Please ensure this path aligns with the expected navigation flow for public pages.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx (1)
3-5
: LGTM! Proper imports for the new redirect functionality.The imports for
redirectToContractLandingPage
andshouldRenderNewPublicPage
are correctly added to support the new conditional logic.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx (1)
7-10
: LGTM! Consistent imports with other shared pages.The imports are correctly added and consistent with the pattern established in other shared page files.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (1)
7-7
: LGTM! Import is consistent with the established pattern.The import for
shouldRenderNewPublicPage
follows the same pattern as other shared page files.apps/dashboard/src/app/(app)/(dashboard)/contracts/layout.tsx (1)
1-16
: LGTM! Clean layout component implementation.The layout component follows React best practices with proper TypeScript typing and a clean structure. The TeamHeader integration provides consistent navigation across the dashboard.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx (2)
3-5
: LGTM! Proper imports for new public page functionality.The imports are correctly added to support the conditional redirect logic for new public pages.
23-33
: LGTM! Well-implemented conditional redirect logic.The conditional check correctly prevents rendering the sources page for new public page types (like ERC20) when no project metadata is present. The logic is properly placed after validation and uses the appropriate utility functions.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx (2)
4-6
: LGTM! Consistent imports for new public page functionality.The imports correctly support the conditional redirect logic, following the same pattern as other shared pages.
26-36
: LGTM! Consistent conditional redirect implementation.The conditional logic correctly prevents rendering the explorer page for new public page types when no project metadata is present. This follows the same well-established pattern used in other shared pages, ensuring consistency across the application.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx (1)
8-8
: LGTM! Consistent implementation of new public page redirect logic.The conditional redirect logic is well-implemented and follows the established pattern across other shared pages. The performance optimization of checking
projectMeta
before callingshouldRenderNewPublicPage
is good practice.Also applies to: 26-36
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx (1)
4-4
: LGTM! Consistent redirect pattern implementation.The implementation matches the pattern used in other shared pages and includes a helpful comment explaining the business logic. The conditional check structure is optimal for performance.
Also applies to: 6-6, 25-35
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PublicPageConnectButton.tsx (1)
1-35
: LGTM! Well-structured connect button component.The component properly handles theming, chain data fetching, and ConnectButton configuration. The explanatory comment about autoConnect being handled elsewhere is helpful for maintainability.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (1)
19-71
: LGTM! Well-structured responsive layout for ERC20 public page.The component properly implements a responsive design with appropriate component composition. The conditional rendering for mobile vs desktop views of the BuyTokenEmbed is a good UX pattern.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1)
3-3
: LGTM: Import statements are correctly structured.The import paths for the utility functions are appropriate and follow the established patterns in the codebase.
Also applies to: 6-6
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PayEmbedSection.tsx (2)
8-14
: Good component interface design.The props interface is well-defined with appropriate TypeScript types using thirdweb's built-in types. The component accepts all necessary parameters for token purchasing functionality.
17-44
: Well-configured PayEmbed with good defaults.The PayEmbed configuration is comprehensive and user-friendly:
- Proper theme integration with the dashboard
- Sensible defaults (amount: "1", autoConnect: false)
- Appropriate edit restrictions (only amount can be edited)
- Good styling with rounded corners and full width
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (2)
5-5
: Type definition is extensible for future contract types.The
NewPublicPageType
union type is well-designed for future expansion beyond just "erc20". This provides a clear contract for the return value.
7-27
: Robust implementation with proper error handling.The function is well-structured with:
- Clear return type union (
false | { type: NewPublicPageType }
)- Proper error handling for
resolveFunctionSelectors
- Early return patterns for better readability
- Logical flow for contract type detection
apps/dashboard/src/components/analytics/empty-chart-state.tsx (4)
2-2
: Good import organization with new dependencies.The imports are well-organized and include the necessary new components (
LoadingDots
,Area
,AreaChart
) for the enhanced functionality.Also applies to: 5-5
24-27
: Excellent type safety with the new required prop.The enhanced component interface properly requires the
type
prop with a constrained union type, ensuring type safety and preventing runtime errors.
57-91
: Well-implemented conditional rendering for different chart types.The conditional rendering logic is clean and provides appropriate configuration for both bar and area charts. The area chart includes proper gradient styling that matches the design system.
42-43
: Improved loading state with consistent component.The switch from
Spinner
toLoadingDots
provides better consistency with the dashboard's loading patterns, and the opacity adjustment (bg-muted/30
) maintains good visual hierarchy.apps/dashboard/src/@/components/blocks/charts/area-chart.tsx (3)
49-54
: LGTM! Well-structured prop additions.The new optional props enhance the flexibility of the component while maintaining backward compatibility. The additions are well-typed and follow consistent naming conventions.
63-63
: Good implementation of className forwarding.The className props are properly applied to the Card and CardContent components with appropriate conditional logic using the
cn
utility.Also applies to: 77-79
84-86
: Consistent EmptyChartState integration.The EmptyChartState component properly receives the
type="area"
prop and forwards the customemptyChartState
element, maintaining consistency with the pattern established in other chart components.apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (5)
14-14
: Good import organization.The new imports for
TeamHeader
andshouldRenderNewPublicPage
are appropriately placed and support the new functionality being added.Also applies to: 23-23
58-68
: Consistent TeamHeader integration for localhost.The TeamHeaderLayout wrapper is properly applied to the localhost contract layout, ensuring consistent header presence across different environments.
71-77
: Well-implemented new public page logic.The conditional check properly handles the new public page rendering flow by:
- Only applying when
projectMeta
is undefined (public context)- Using the utility function to determine if new page should render
- Returning children directly when the new page should be shown
114-141
: Comprehensive layout enhancement.The TeamHeaderLayout wrapper and NebulaChatButton integration enhance the user experience with:
- Consistent team header across all contract pages
- Contextual AI chat functionality with contract-specific prompts
- Proper prop forwarding and conditional rendering
234-243
: Clean and effective TeamHeaderLayout component.The component provides a clean separation of concerns with:
- Proper flexbox layout structure
- Consistent border styling matching the design system
- Simple prop interface accepting only children
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (3)
3-4
: Well-organized imports for new functionality.The new imports properly support the public page rendering logic with:
- Type imports for contract and chain metadata
- NewPublicPageType and utility function imports
- ERC20PublicPage component import
Also applies to: 8-11, 15-15
45-58
: Consistent public page rendering logic.The conditional logic follows the same pattern as in
shared-layout.tsx
, ensuring consistent behavior across the application when determining whether to render new public pages.
86-106
: Extensible helper component design.The
RenderNewPublicContractPage
component uses a clean switch case pattern that:
- Currently supports ERC20 public pages
- Is easily extensible for future contract types
- Properly forwards all necessary props to the specific page component
- Has appropriate fallback handling
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx (1)
93-99
: LGTM! Clean explorer filtering logic.The explorer filtering logic correctly follows EIP-3091 standards and limits results appropriately.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts (1)
26-28
: Reconsider the disabled query behaviors.Disabling retries, retryOnMount, and refetchOnWindowFocus might impact user experience. These features are generally beneficial for handling network issues and ensuring data freshness.
Can you clarify why these query behaviors are disabled? Consider enabling them unless there's a specific reason:
-retry: false, -retryOnMount: false, -refetchOnWindowFocus: false, +retry: 3, +retryOnMount: true, +refetchOnWindowFocus: true,apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx (2)
224-225
: LGTM! Good separation of loading states.The code properly separates token transfers pending state from the combined pending state, allowing for fine-grained loading control.
234-234
: Good fallback for token decimals.Using 18 as the default decimal value is a sensible fallback for ERC-20 tokens.
...app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx
Show resolved
Hide resolved
.../src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
Outdated
Show resolved
Hide resolved
...shboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
Outdated
Show resolved
Hide resolved
...shboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
Outdated
Show resolved
Hide resolved
...shboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
Show resolved
Hide resolved
...ashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
Outdated
Show resolved
Hide resolved
...shboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts
Show resolved
Hide resolved
...ard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx
Show resolved
Hide resolved
size-limit report 📦
|
ed5fd50
to
eee64bf
Compare
eee64bf
to
9a99ba7
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 (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx (2)
95-102
: Fix precision loss in token amount display.Based on previous feedback, converting the string result from
toTokens()
toNumber()
can lose precision for very large token amounts exceedingNumber.MAX_SAFE_INTEGER
.Since
Intl.NumberFormat.format()
can handle string inputs, remove theNumber()
conversion:-{tokenAmountFormatter.format( - Number( - toTokens( - BigInt(transfer.amount), - props.tokenMetadata.decimals, - ), - ), -)} +{tokenAmountFormatter.format( + toTokens( + BigInt(transfer.amount), + props.tokenMetadata.decimals, + ), +)}
204-216
: Add error handling for failed token transfer queries.The component handles pending and success states but doesn't handle error states. Users won't be able to distinguish between "no transfers found" and "failed to load data".
Consider adding error state handling:
const tokenQuery = useTokenTransfers({ chainId: props.clientContract.chain.id, contractAddress: props.clientContract.address, page, limit: rowsPerPage, }); +const hasError = tokenQuery.isError;
Then update the UI to show error states when
hasError
is true.
🧹 Nitpick comments (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx (1)
211-211
: Clarify the eslint disable comment.The
// eslint-disable-next-line no-restricted-syntax
comment lacks explanation for why this rule is disabled. Consider documenting the reason or finding an alternative approach.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
apps/dashboard/src/@/components/ui/decimal-input.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx
(4 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.stories.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-sale.tsx
(1 hunks)apps/dashboard/src/components/buttons/MismatchButton.tsx
(2 hunks)apps/dashboard/src/components/buttons/TransactionButton.tsx
(3 hunks)apps/dashboard/src/components/icons/brand-icons/DiscordIcon.tsx
(1 hunks)apps/dashboard/src/components/icons/brand-icons/TelegramIcon.tsx
(1 hunks)apps/dashboard/src/components/icons/brand-icons/XIcon.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (16)
- apps/dashboard/src/components/icons/brand-icons/DiscordIcon.tsx
- apps/dashboard/src/components/buttons/TransactionButton.tsx
- apps/dashboard/src/components/icons/brand-icons/TelegramIcon.tsx
- apps/dashboard/src/components/icons/brand-icons/XIcon.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-sale.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx
- apps/dashboard/src/@/components/ui/decimal-input.tsx
- apps/dashboard/src/components/buttons/MismatchButton.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.stories.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.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]/public-pages/erc20/erc20.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]/overview/components/Analytics.tsx
🧰 Additional context used
🧠 Learnings (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx (1)
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx:75-76
Timestamp: 2025-05-27T19:55:53.707Z
Learning: Using array index as React keys is acceptable for skeleton loading rows since they are temporary, fixed-count placeholder elements that don't represent dynamic data and get completely replaced once loading completes. The biome lint rule against array index keys is overly strict in this loading skeleton context.
🧬 Code Graph Analysis (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx (4)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts (2)
TokenTransfersData
(5-17)useTokenTransfers
(19-54)apps/dashboard/src/@/components/blocks/wallet-address.tsx (1)
WalletAddress
(22-167)apps/dashboard/src/@/components/ui/button.tsx (1)
Button
(67-67)packages/thirdweb/src/exports/thirdweb.ts (1)
ThirdwebContract
(71-71)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: Size
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Lint Packages
- GitHub Check: Unit Tests
- GitHub Check: Build Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (3)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx (3)
1-33
: LGTM! Clean imports and appropriate number formatting setup.The compact number formatter configuration is well-suited for displaying token amounts in a transfer list, with sensible precision limits.
172-192
: LGTM! Well-structured skeleton loading component.The skeleton dimensions and styling appropriately match the actual data rows, providing good visual feedback during loading states.
218-237
: LGTM! Clean component structure and prop management.The component properly manages pagination state, tracks loading states, and provides appropriate fallbacks for explorer URLs.
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: 5
🧹 Nitpick comments (6)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (2)
5-5
: Consider future extensibility of the type definition.The type alias is currently limited to "erc20" but appears designed for extension. Consider adding JSDoc documentation to clarify the intended usage and extension pattern.
+/** + * Supported contract types for new public pages + */ export type NewPublicPageType = "erc20";
7-31
: Function logic is solid but could benefit from performance optimizations.The function correctly handles error scenarios and provides a clear API. However, there are opportunities for improvement:
- Caching: Since this function may be called multiple times for the same contract, consider implementing result caching
- Error logging: Silent error handling makes debugging difficult in development environments
- Documentation: Add JSDoc comments for better developer experience
Consider this enhanced version:
+/** + * Determines if a contract should render a new public page variant + * @param contract - The ThirdwebContract to analyze + * @returns Promise resolving to false or an object with the page type + */ export async function shouldRenderNewPublicPage( contract: ThirdwebContract, ): Promise<false | { type: NewPublicPageType }> { try { const functionSelectors = await resolveFunctionSelectors(contract).catch( - () => undefined, + (error) => { + if (process.env.NODE_ENV === 'development') { + console.warn('Failed to resolve function selectors:', error); + } + return undefined; + }, ); if (!functionSelectors) { return false; } const isERC20Contract = isERC20(functionSelectors); if (isERC20Contract) { return { type: "erc20", }; } return false; - } catch { + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.warn('Error in shouldRenderNewPublicPage:', error); + } return false; } }apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx (4)
356-356
: Remove debug console.log from production code.The console.log statement should be removed before deployment to production.
- console.log("value", value);
65-147
: Consider extracting complex mutation logic for better maintainability.The
approveAndClaim
mutation contains complex multi-step logic that could benefit from extraction into a custom hook or separate utility function. This would improve testability and reusability.Consider creating a custom hook like
useTokenClaimTransaction
that encapsulates this logic:function useTokenClaimTransaction(props: { contract: ThirdwebContract }) { // Extract the mutation logic here return { approveAndClaim, stepsUI }; }This would make the component more focused on UI concerns.
57-63
: Simplify step UI state management.The
stepsUI
state type is complex with nested optional properties. Consider using a more explicit state machine pattern or simpler state structure.- const [stepsUI, setStepsUI] = useState< - | undefined - | { - approve: undefined | "idle" | "pending" | "success" | "error"; - claim: "idle" | "pending" | "success" | "error"; - } - >(undefined); + type TransactionStep = "idle" | "pending" | "success" | "error"; + const [transactionSteps, setTransactionSteps] = useState<{ + approve?: TransactionStep; + claim?: TransactionStep; + }>({});
171-171
: Clarify the purpose of the hardcoded quantity value.The comment "not relevant" for
quantity: 1n
is unclear. Consider adding a more descriptive comment explaining why this value doesn't matter for the claim parameters query.- quantity: 1n, // not relevant + quantity: 1n, // Quantity doesn't affect pricing in claim params, only used for validation
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (72)
apps/dashboard/src/@/actions/getWalletNFTs.ts
(2 hunks)apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx
(5 hunks)apps/dashboard/src/@/components/blocks/charts/area-chart.tsx
(4 hunks)apps/dashboard/src/@/components/blocks/charts/bar-chart.tsx
(1 hunks)apps/dashboard/src/@/components/ui/LoadingDots.tsx
(1 hunks)apps/dashboard/src/@/components/ui/decimal-input.tsx
(1 hunks)apps/dashboard/src/@/constants/public-envs.ts
(1 hunks)apps/dashboard/src/@/constants/thirdweb.server.ts
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(bridge)/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx
(3 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/metadata-header.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx
(4 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-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/PublicPageConnectButton.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.stories.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PayEmbedSection.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.stories.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_utils/getCurrencyMeta.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx
(5 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx
(4 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/tx/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/chainlist/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/contracts/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/explore/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/layout.tsx
(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/profile/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/published-contract/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/support/layout.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/tools/layout.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-sale.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/components/Analytics/BarChart.tsx
(1 hunks)apps/dashboard/src/app/bridge/constants.ts
(2 hunks)apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx
(1 hunks)apps/dashboard/src/app/pay/constants.ts
(2 hunks)apps/dashboard/src/components/analytics/empty-chart-state.tsx
(2 hunks)apps/dashboard/src/components/buttons/MismatchButton.tsx
(2 hunks)apps/dashboard/src/components/buttons/TransactionButton.tsx
(3 hunks)apps/dashboard/src/components/contract-components/tables/contract-table.tsx
(2 hunks)apps/dashboard/src/components/icons/brand-icons/DiscordIcon.tsx
(1 hunks)apps/dashboard/src/components/icons/brand-icons/TelegramIcon.tsx
(1 hunks)apps/dashboard/src/components/icons/brand-icons/XIcon.tsx
(1 hunks)apps/dashboard/src/data/analytics/contract-event-breakdown.ts
(2 hunks)apps/dashboard/src/data/analytics/contract-events.ts
(2 hunks)apps/dashboard/src/data/analytics/contract-function-breakdown.ts
(2 hunks)apps/dashboard/src/data/analytics/contract-transactions.ts
(2 hunks)apps/dashboard/src/data/analytics/contract-wallet-analytics.ts
(2 hunks)apps/dashboard/src/data/analytics/total-contract-events.ts
(2 hunks)apps/dashboard/src/data/analytics/total-contract-transactions.ts
(2 hunks)apps/dashboard/src/data/analytics/total-unique-wallets.ts
(2 hunks)
💤 Files with no reviewable changes (1)
- apps/dashboard/src/app/(app)/(dashboard)/layout.tsx
🚧 Files skipped from review as they are similar to previous changes (69)
- apps/dashboard/src/@/constants/public-envs.ts
- apps/dashboard/src/@/actions/getWalletNFTs.ts
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx
- apps/dashboard/src/data/analytics/contract-transactions.ts
- apps/dashboard/src/@/constants/thirdweb.server.ts
- apps/dashboard/src/data/analytics/contract-event-breakdown.ts
- apps/dashboard/src/data/analytics/total-unique-wallets.ts
- apps/dashboard/src/data/analytics/contract-function-breakdown.ts
- apps/dashboard/src/data/analytics/total-contract-events.ts
- apps/dashboard/src/app/pay/constants.ts
- apps/dashboard/src/data/analytics/total-contract-transactions.ts
- apps/dashboard/src/app/(app)/team/components/Analytics/BarChart.tsx
- apps/dashboard/src/@/components/blocks/charts/bar-chart.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/metadata-header.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx
- apps/dashboard/src/components/buttons/TransactionButton.tsx
- apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx
- apps/dashboard/src/app/(app)/(dashboard)/tools/layout.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx
- apps/dashboard/src/data/analytics/contract-events.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx
- apps/dashboard/src/@/components/ui/LoadingDots.tsx
- apps/dashboard/src/data/analytics/contract-wallet-analytics.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx
- apps/dashboard/src/components/buttons/MismatchButton.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx
- apps/dashboard/src/app/(app)/(dashboard)/published-contract/layout.tsx
- apps/dashboard/src/app/(app)/(dashboard)/support/layout.tsx
- apps/dashboard/src/components/icons/brand-icons/DiscordIcon.tsx
- apps/dashboard/src/app/(app)/(dashboard)/explore/layout.tsx
- apps/dashboard/src/app/bridge/constants.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx
- apps/dashboard/src/app/(app)/(dashboard)/contracts/layout.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx
- apps/dashboard/src/components/icons/brand-icons/XIcon.tsx
- apps/dashboard/src/app/(app)/(dashboard)/profile/layout.tsx
- apps/dashboard/src/components/icons/brand-icons/TelegramIcon.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(bridge)/layout.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/chainlist/layout.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]/tx/layout.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx
- apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx
- apps/dashboard/src/components/contract-components/tables/contract-table.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_utils/getCurrencyMeta.ts
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-sale.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PublicPageConnectButton.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.stories.tsx
- apps/dashboard/src/@/components/blocks/charts/area-chart.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx
- apps/dashboard/src/components/analytics/empty-chart-state.tsx
- apps/dashboard/src/@/components/ui/decimal-input.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.stories.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PayEmbedSection.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts
- 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]/overview/components/Analytics.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Lint Packages
- GitHub Check: Size
- GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts (1)
1-3
: LGTM! Clean and focused imports.The imports are well-organized and include only the necessary dependencies for the utility function.
...board/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/newPublicPage.ts
Show resolved
Hide resolved
...[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
Show resolved
Hide resolved
...[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
Show resolved
Hide resolved
...[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
Show resolved
Hide resolved
...[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
Show resolved
Hide resolved
f485b34
to
3a7f307
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 (4)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx (4)
49-49
: Add input validation for quantity state.The quantity state lacks validation which could allow invalid inputs like negative numbers or non-numeric values, potentially causing calculation errors or poor user experience.
149-191
: Add error handling for claim parameters query.The claimParamsQuery lacks proper error handling, which could leave the UI in an unclear state when the query fails.
274-292
: Add loading state for claim parameters query.The TransactionButton doesn't provide visual feedback when claim parameters are loading, which could confuse users about why the button is disabled.
352-358
: Improve input validation and accessibility.The PriceInput component has a debug console.log statement and lacks proper input validation and accessibility features.
🧹 Nitpick comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx (2)
77-77
: Remove redundant String conversion.The
quantity
variable is already a string, so theString()
conversion is unnecessary.- quantity: String(quantity), + quantity: quantity,
195-313
: Consider adding max purchasable amount validation.The UI shows a commented line about maximum purchasable tokens but doesn't implement this validation. Consider adding logic to prevent users from entering quantities that exceed their purchase limits.
This would improve user experience by preventing failed transactions due to quantity limits.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
apps/dashboard/src/@/components/ui/decimal-input.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx
(4 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.stories.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-page-impl.tsx
(5 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-page.client.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-page.stories.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-sale.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/launch/launch-token.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/page.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/tracking.ts
(1 hunks)apps/dashboard/src/components/buttons/MismatchButton.tsx
(2 hunks)apps/dashboard/src/components/buttons/TransactionButton.tsx
(3 hunks)apps/dashboard/src/components/icons/brand-icons/DiscordIcon.tsx
(1 hunks)apps/dashboard/src/components/icons/brand-icons/TelegramIcon.tsx
(1 hunks)apps/dashboard/src/components/icons/brand-icons/XIcon.tsx
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-page.stories.tsx
🚧 Files skipped from review as they are similar to previous changes (16)
- apps/dashboard/src/components/buttons/TransactionButton.tsx
- apps/dashboard/src/components/icons/brand-icons/TelegramIcon.tsx
- apps/dashboard/src/components/buttons/MismatchButton.tsx
- apps/dashboard/src/components/icons/brand-icons/XIcon.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-sale.tsx
- apps/dashboard/src/components/icons/brand-icons/DiscordIcon.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.stories.tsx
- apps/dashboard/src/@/components/ui/decimal-input.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.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]/overview/components/Analytics.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-page-impl.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/tracking.ts (1)
getTokenStepTrackingData
(17-29)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: Size
- GitHub Check: Build Packages
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Unit Tests
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (10)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/page.tsx (1)
60-61
: LGTM! Props correctly forwarded.The
teamSlug
andprojectSlug
props are properly extracted from the route parameters and forwarded to theCreateTokenAssetPage
component. This maintains consistent team/project context throughout the token creation flow.apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-page.client.tsx (2)
38-39
: LGTM! Props interface correctly extended.The component props are properly extended with
teamSlug
andprojectSlug
to support the new routing requirements.
119-120
: LGTM! Props appropriately forwarded to launch component.The team and project slugs are correctly passed to the
LaunchTokenStatus
component only when the current step is "launch", ensuring context is available when needed for contract link generation.apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/launch/launch-token.tsx (2)
36-37
: LGTM! Required props added for enhanced routing.The component correctly accepts
teamSlug
andprojectSlug
props to support context-aware contract link generation.
105-107
: LGTM! Contract link now includes team/project context.The contract link construction has been improved to include team and project slugs, providing better navigation context and aligning with the new routing structure for ERC20 public contract pages.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/tracking.ts (1)
18-18
: LGTM! Action type extended for deployment tracking.The addition of
"deploy"
to the action type union enables proper tracking of deployment events, aligning with the enhanced analytics requirements for the token creation flow.apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-page-impl.tsx (4)
41-42
: LGTM: Props addition aligns with team/project context integration.The addition of
teamSlug
andprojectSlug
props is consistent with the PR's objective to integrate team and project context throughout the dashboard application.
56-62
: LGTM: Deployment tracking enhancement with granular status tracking.The new tracking event using
getTokenStepTrackingData
provides more granular tracking for the deployment process. This complements the existinggetTokenDeploymentTrackingData
tracking and follows the same pattern used for other actions like airdrop, mint, and claim-conditions.
103-109
: LGTM: Consistent deployment tracking for success and error cases.The tracking events for deployment success and error cases properly follow the established pattern and are placed in the correct locations (after successful deployment and in the catch block respectively). This provides complete coverage of the deployment lifecycle for analytics purposes.
Also applies to: 131-137
381-382
: LGTM: Props correctly forwarded to UI component.The
teamSlug
andprojectSlug
props are properly passed down to theCreateTokenAssetPageUI
component, maintaining the data flow consistency required for the team/project context integration.
Merge activity
|
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR primarily focuses on enhancing the dashboard's functionality and user interface by updating environment variable usage, improving component layouts, and refining analytics features. It also introduces new components and modifies existing ones for better data handling and presentation. ### Detailed summary - Added `NEXT_PUBLIC_DASHBOARD_CLIENT_ID` to `public-envs.ts`. - Updated `CreateTokenAssetPage` to pass `teamSlug` and `projectSlug`. - Changed `projectSlug` to use `project.slug` in `marketplace` page. - Enhanced `EmptyChartState` to accept a `type` prop. - Updated `getTokenStepTrackingData` to include "deploy" action. - Introduced `LoadingDots` component for loading states. - Refactored multiple layout components to include `TeamHeader`. - Added new public page handling logic in various components. - Updated analytics functions to utilize the new client ID. - Improved error handling and response management in analytics API calls. - Added `DecimalInput` component to replace standard input in `token-sale.tsx`. > The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.stories.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.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]/public-pages/erc20/_components/PriceChart.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx` > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added new layout components with team headers for various dashboard sections. - Introduced `LoadingDots` component for animated loading indicators. - Added `PublicPageConnectButton` and `PageHeader` components for public pages. - Implemented public ERC-20 token page with price charts, token stats, recent transfers, and buy token embed. - Added token claim card UI with transaction step feedback for purchasing tokens. - Added hooks for fetching token price data and token transfers. - Added utility to fetch currency metadata for tokens. - Added comprehensive contract analytics overview component. - Introduced `DecimalInput` component for validated decimal input handling. - Added new social media brand icons for Discord and Telegram. - **Improvements** - Enhanced area and bar charts with customizable styles, tooltip formatting, and explicit empty state types. - Improved empty chart state visuals with new area chart gradients and replaced spinner with animated dots. - Unified environment variable usage for client IDs across API calls and client initializations. - Updated contract overview to display call-to-action banner linking to public asset pages for ERC-20 tokens. - Enhanced contract table to conditionally show contract address or asset page links based on context. - Improved primary dashboard button to link to asset pages when applicable. - Added redirects to public landing pages for unsupported contract views lacking project metadata. - Wrapped existing layouts with conditional team headers for consistent UI in public/private views. - Added pagination and detailed tables for recent token transfers. - Updated project slug usage in marketplace listings for accuracy. - Introduced dynamic time precision handling in analytics charts and tooltips. - Added optional balance check control to transaction and mismatch buttons. - Replaced local decimal input component with shared validated decimal input component. - Added optional target attribute for call-to-action links in upsell banners. - Refined accessibility and sizing of icon components. - **Bug Fixes** - Fixed environment variable naming for client IDs to ensure consistent API integration. - **Refactor** - Standardized header and layout components for a unified dashboard experience. - Replaced spinner with animated dots in loading states for smoother UX. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
3a7f307
to
3b1e16c
Compare
PR-Codex overview
This PR focuses on enhancing the dashboard application by adding new features, modifying existing components, and improving code organization. Key updates include the introduction of new constants, layout adjustments, and function enhancements for better user experience.
Detailed summary
NEXT_PUBLIC_DASHBOARD_CLIENT_ID
constant.CreateTokenAssetPage
to acceptteamSlug
andprojectSlug
.BarChart
andEmptyChartState
components to include new props.TeamHeader
in multiple layouts for consistency.LoadingDots
component.NEXT_PUBLIC_DASHBOARD_CLIENT_ID
for authentication.DecimalInput
component for better usability.Summary by CodeRabbit
New Features
LoadingDots
component for animated loading indicators.PublicPageConnectButton
andPageHeader
components for public pages.DecimalInput
component for validated decimal input handling.Improvements
Bug Fixes
Refactor