-
Notifications
You must be signed in to change notification settings - Fork 567
[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: #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
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