Skip to content

[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

Merged
merged 1 commit into from
May 29, 2025

Conversation

MananTank
Copy link
Member

@MananTank MananTank commented May 27, 2025


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

  • Added NEXT_PUBLIC_DASHBOARD_CLIENT_ID constant.
  • Modified CreateTokenAssetPage to accept teamSlug and projectSlug.
  • Updated BarChart and EmptyChartState components to include new props.
  • Enhanced tracking functions with a new action type.
  • Introduced TeamHeader in multiple layouts for consistency.
  • Improved loading states with the new LoadingDots component.
  • Added public page handling logic to various components.
  • Updated API calls to use NEXT_PUBLIC_DASHBOARD_CLIENT_ID for authentication.
  • Refactored DecimalInput component for better usability.
  • Implemented new public contract page rendering logic.

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}

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.
    • Enhanced deployment tracking with new events and extended props to include team and project slugs.
    • Improved navigation links to include team and project context in token launch and asset pages.
  • 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.

@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 27, 2025 19:17 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 27, 2025 19:17 Inactive
Copy link

vercel bot commented May 27, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
thirdweb-www ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 29, 2025 11:10pm
4 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Skipped (Inspect) May 29, 2025 11:10pm
login ⬜️ Skipped (Inspect) May 29, 2025 11:10pm
thirdweb_playground ⬜️ Skipped (Inspect) May 29, 2025 11:10pm
wallet-ui ⬜️ Skipped (Inspect) May 29, 2025 11:10pm

@vercel vercel bot temporarily deployed to Preview – login May 27, 2025 19:17 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 27, 2025 19:17 Inactive
Copy link

linear bot commented May 27, 2025

Copy link

changeset-bot bot commented May 27, 2025

⚠️ No Changeset found

Latest commit: 3b1e16c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented May 27, 2025

Walkthrough

This 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

Files/Groups Change Summary
.../public-envs.ts, .../thirdweb.server.ts, .../getWalletNFTs.ts, .../live-stats.tsx, .../CustomChatButton.tsx, .../constants.ts, .../contract-event-breakdown.ts, .../contract-events.ts, .../contract-function-breakdown.ts, .../contract-transactions.ts, .../contract-wallet-analytics.ts, .../total-contract-events.ts, .../total-contract-transactions.ts, .../total-unique-wallets.ts, .../bridge/constants.ts Standardized environment variable name from NET_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID to NEXT_PUBLIC_DASHBOARD_CLIENT_ID throughout imports and usages.
.../area-chart.tsx, .../bar-chart.tsx, .../empty-chart-state.tsx, .../LoadingDots.tsx Enhanced chart components with new props for styling and tooltip formatting; updated empty state rendering to differentiate chart types; replaced spinner with animated loading dots.
.../public-pages/erc20/erc20.tsx, .../public-pages/erc20/_components/ContractHeader.tsx, .../public-pages/erc20/_components/PayEmbedSection.tsx, .../public-pages/erc20/_components/PriceChart.tsx, .../public-pages/erc20/_components/RecentTransfers.tsx, .../public-pages/erc20/_hooks/useTokenPriceData.ts, .../public-pages/erc20/_hooks/useTokenTransfers.ts, .../public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx, .../public-pages/erc20/_components/claim-tokens/claim-tokens-ui.stories.tsx, .../public-pages/erc20/_components/contract-analytics/contract-analytics.tsx Introduced new ERC20 public contract page, including UI components for contract header, price chart, buy token embed, recent transfers, claim token card, contract analytics, and supporting data hooks and stories.
.../public-pages/_components/PageHeader.tsx, .../public-pages/_components/PublicPageConnectButton.tsx Added new components for the public page header and a public page connect button.
.../shared-overview-page.tsx, .../shared-layout.tsx, .../newPublicPage.ts, .../analytics/shared-analytics-page.tsx, .../claim-conditions/shared-claim-conditions-page.tsx, .../code/shared-code-page.tsx, .../cross-chain/shared-cross-chain-page.tsx, .../events/shared-events-page.tsx, .../explorer/shared-explorer-page.tsx, .../permissions/shared-permissions-page.tsx, .../settings/shared-settings-page.tsx, .../sources/shared-sources-page.tsx, .../tokens/shared-page.tsx Added logic to detect and render new ERC20 public page, and redirect away from legacy subpages when applicable.
.../layout.tsx (multiple dashboard subfolders: bridge, chainPage, chainlist, contracts, explore, profile, published-contract, support, tx) Added or updated layout components to include a persistent TeamHeader above content for consistent UI.
.../tools/layout.tsx Inserted TeamHeader above sidebar layout for tool pages.
.../layout.tsx (dashboard root) Removed TeamHeader from the root dashboard layout, delegating header responsibility to sub-layouts.
.../direct-listings/page.tsx Updated to use project slug from fetched project data instead of route params.
.../contract-table.tsx Modified contract address column rendering to conditionally show either contract address copy button or asset page link based on variant prop.
.../UpsellBannerCard.tsx Added optional target prop to CTA; adjusted padding and visibility for icon container; updated link target attribute.
.../_layout/primary-dashboard-button.tsx Changed behavior to render a button linking to the asset page when projectMeta is present instead of rendering nothing.
.../overview/ContractOverviewPage.tsx Added conditional ERC20 upsell banner with link to public asset page.
.../public-pages/erc20/_utils/getCurrencyMeta.ts Added utility to fetch currency metadata (decimals, symbol) for native and non-native tokens.
.../buttons/MismatchButton.tsx, .../buttons/TransactionButton.tsx Added optional checkBalance prop to control balance checking behavior in mismatch and transaction buttons.
.../overview/components/Analytics.tsx Refactored analytics data aggregation to support dynamic precision (day or hour) based on date range; updated tooltip label formatting accordingly.
.../app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-sale.tsx Replaced local DecimalInput component with imported shared DecimalInput component for decimal input handling.

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
Loading
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
Loading

Assessment against linked issues

Objective Addressed Explanation
Implement a new ERC20 public contract page with custom UI, statistics, chart, buy functionality, recent transfers, and appropriate routing (TOOL-4621)

Possibly related PRs

Suggested labels

packages, SDK

Suggested reviewers

  • MananTank
  • joaquim-verges

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (2)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.
  • ERC-20: Entity not found: Issue - Could not find referenced Issue.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@MananTank MananTank marked this pull request as ready for review May 27, 2025 19:17
@MananTank MananTank requested review from a team as code owners May 27, 2025 19:17
@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label May 27, 2025
Copy link
Member Author

MananTank commented May 27, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

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.

@MananTank MananTank marked this pull request as draft May 27, 2025 19:18
Copy link

codecov bot commented May 27, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 55.62%. Comparing base (1f42ad2) to head (3b1e16c).
Report is 1 commits behind head on main.

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           
Flag Coverage Δ
packages 55.62% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 shared DashboardLayoutWithTeamHeader 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 display
  • TokenMetricsGrid for market cap and holders
  • TokenStatsContainer as the main orchestrator
apps/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 and log_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

📥 Commits

Reviewing files that changed from the base of the PR and between bb7a898 and ed5fd50.

📒 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 updated EmptyChartState component API requirements as shown in the relevant code snippets from apps/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 named NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID, aligning with the constant defined in public-envs.ts.


16-18: Update placeholder replacement to use the new client ID
Replaces the ${THIRDWEB_API_KEY} placeholder with NEXT_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 import NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID from public-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 named NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID from public-envs to standardize environment variable usage.


31-31: Use updated client ID in request header
Replaced the old constant with NEXT_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 use NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID, reflecting the renamed environment variable.


31-31: Use updated client ID in headers
Ensures the analytics fetch includes the new NEXT_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 with NEXT_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 to NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID, fixing the typo in the prefix and aligning with the actual constant definition in public-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 to NEXT_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 of params.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 ts

Length 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
the projectSlug prop now correctly uses project.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 to NEXT_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. If chain.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 the slug 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, while slug 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 the slug 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:


No Guard Needed: chain.slug Is Always Defined

The ChainMetadata interface in the thirdweb/chains SDK declares slug: string (no ?), so it’s a required property. Removing the conditional around the <Link> is safe with respect to chain.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 to NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID, which follows Next.js environment variable conventions and aligns with the constant definition in apps/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 the EmptyChartState component ensures the empty state visualization matches the bar chart type. This aligns with the enhanced EmptyChartState 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 and shouldRenderNewPublicPage 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:

  1. Only executes when projectMeta is undefined (appropriate guard condition)
  2. Uses shouldRenderNewPublicPage to determine if the contract should render a new public page variant
  3. 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:

  1. Proper structure: Uses a flex column layout with the TeamHeader positioned at the top
  2. Consistent styling: Applies consistent border and background styling for the header section
  3. Type safety: Correctly types the children prop as React.ReactNode
  4. 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 and shouldRenderNewPublicPage 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 calling shouldRenderNewPublicPage 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 to LoadingDots 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 custom emptyChartState 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 and shouldRenderNewPublicPage 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.

Copy link
Contributor

github-actions bot commented May 27, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 62.11 KB (0%) 1.3 s (0%) 279 ms (+32.85% 🔺) 1.6 s
thirdweb (cjs) 345.28 KB (0%) 7 s (0%) 1.6 s (+4.27% 🔺) 8.5 s
thirdweb (minimal + tree-shaking) 5.7 KB (0%) 114 ms (0%) 115 ms (+779.72% 🔺) 229 ms
thirdweb/chains (tree-shaking) 531 B (0%) 11 ms (0%) 14 ms (+99.24% 🔺) 24 ms
thirdweb/react (minimal + tree-shaking) 19.52 KB (0%) 391 ms (0%) 42 ms (+45.68% 🔺) 432 ms

@MananTank MananTank force-pushed the 05-28-_tool-4621_new_erc20_public_contract_page branch from ed5fd50 to eee64bf Compare May 27, 2025 20:09
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 27, 2025 20:09 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 27, 2025 20:09 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 27, 2025 20:09 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 27, 2025 20:09 Inactive
@MananTank MananTank force-pushed the 05-28-_tool-4621_new_erc20_public_contract_page branch from eee64bf to 9a99ba7 Compare May 28, 2025 17:26
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 28, 2025 17:26 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 28, 2025 17:26 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 28, 2025 17:26 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 28, 2025 17:26 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 29, 2025 21:44 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 29, 2025 21:44 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 29, 2025 21:44 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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() to Number() can lose precision for very large token amounts exceeding Number.MAX_SAFE_INTEGER.

Since Intl.NumberFormat.format() can handle string inputs, remove the Number() 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

📥 Commits

Reviewing files that changed from the base of the PR and between afe3c51 and c9232a0.

📒 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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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:

  1. Caching: Since this function may be called multiple times for the same contract, consider implementing result caching
  2. Error logging: Silent error handling makes debugging difficult in development environments
  3. 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

📥 Commits

Reviewing files that changed from the base of the PR and between c9232a0 and f485b34.

📒 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.

@MananTank MananTank force-pushed the 05-28-_tool-4621_new_erc20_public_contract_page branch from f485b34 to 3a7f307 Compare May 29, 2025 22:02
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 29, 2025 22:02 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 29, 2025 22:02 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 29, 2025 22:02 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 29, 2025 22:02 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 the String() 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

📥 Commits

Reviewing files that changed from the base of the PR and between f485b34 and 3a7f307.

📒 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 and projectSlug props are properly extracted from the route parameters and forwarded to the CreateTokenAssetPage 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 and projectSlug 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 and projectSlug 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 and projectSlug 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 existing getTokenDeploymentTrackingData 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 and projectSlug props are properly passed down to the CreateTokenAssetPageUI component, maintaining the data flow consistency required for the team/project context integration.

Copy link
Contributor

graphite-app bot commented May 29, 2025

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 -->
@graphite-app graphite-app bot force-pushed the 05-28-_tool-4621_new_erc20_public_contract_page branch from 3a7f307 to 3b1e16c Compare May 29, 2025 23:03
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 29, 2025 23:03 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 29, 2025 23:03 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 29, 2025 23:03 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 29, 2025 23:03 Inactive
@graphite-app graphite-app bot merged commit 3b1e16c into main May 29, 2025
24 checks passed
@graphite-app graphite-app bot deleted the 05-28-_tool-4621_new_erc20_public_contract_page branch May 29, 2025 23:11
@vercel vercel bot temporarily deployed to Production – wallet-ui May 29, 2025 23:11 Inactive
@vercel vercel bot temporarily deployed to Production – docs-v2 May 29, 2025 23:11 Inactive
@vercel vercel bot temporarily deployed to Production – thirdweb_playground May 29, 2025 23:11 Inactive
@vercel vercel bot temporarily deployed to Production – login May 29, 2025 23:11 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dashboard Involves changes to the Dashboard.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants