Skip to content

Add Contract layout in team/project #7152

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 26, 2025

Conversation

MananTank
Copy link
Member

@MananTank MananTank commented May 23, 2025


PR-Codex overview

This PR focuses on enhancing the contract page functionality by introducing teamSlug and projectSlug parameters across various components, improving the organization of contract-related pages, and ensuring better integration with team projects.

Detailed summary

  • Added PublicContractPageParams and ProjectContractPageParams types.
  • Updated components to accept teamSlug and projectSlug.
  • Refactored contract-related page routing to include project metadata.
  • Introduced shared components for contract pages.
  • Enhanced error handling and redirects in contract-related pages.

The following files were skipped due to too many changes: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.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]/explorer/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.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]/split/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.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]/claim-conditions/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.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]/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx, apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/page.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx, apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Enhanced routing to include project and team slugs, enabling project-aware navigation for contract, NFT, marketplace, analytics, permissions, and proposal pages.
    • Passed project metadata (team and project info) throughout various pages and components for contextual consistency.
    • Introduced shared layout and page components for contract overview, NFTs, analytics, permissions, and settings, streamlining the user experience.
  • Refactor

    • Removed internal data fetching, validation, and conditional rendering from pages, delegating logic to shared components.
    • Updated navigation links and breadcrumbs to dynamically incorporate project and team slugs when available.
    • Centralized metadata and layout generation into utility functions to reduce duplication.
  • Bug Fixes

    • Improved handling of missing or invalid project/team data by triggering notFound responses appropriately.
  • Chores

    • Extended component props and interfaces to accept projectMeta objects.
    • Simplified page components to directly render shared components with minimal logic.
    • Updated URL construction to utilize utility functions for project-aware paths.

Copy link

vercel bot commented May 23, 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 26, 2025 9:07pm
4 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Skipped (Inspect) May 26, 2025 9:07pm
login ⬜️ Skipped (Inspect) May 26, 2025 9:07pm
thirdweb_playground ⬜️ Skipped (Inspect) May 26, 2025 9:07pm
wallet-ui ⬜️ Skipped (Inspect) May 26, 2025 9:07pm

@vercel vercel bot temporarily deployed to Preview – wallet-ui May 23, 2025 23:03 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 23, 2025 23:03 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 23, 2025 23:03 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 23, 2025 23:03 Inactive
Copy link
Contributor

coderabbitai bot commented May 23, 2025

Walkthrough

This update propagates a projectMeta prop containing team and project context throughout all contract-related pages and components. It restructures routing to use shared server components that handle data fetching, validation, and conditional rendering based on projectMeta. The changes simplify page logic, centralize URL generation with buildContractPagePath, and enhance navigation consistency across the dashboard.

Changes

File(s) / Path(s) Change Summary
.../direct-listings/ContractDirectListingsPage.client.tsx
.../english-auctions/ContractEnglishAuctionsPage.client.tsx
.../account-permissions/AccountSigners.client.tsx
.../account/AccountPage.client.tsx
.../accounts/AccountsPage.client.tsx
.../claim-conditions/ClaimConditions.client.tsx
.../modules/ContractEditModulesPage.client.tsx
.../nfts/ContractNFTPage.client.tsx
.../nfts/[tokenId]/TokenIdPage.client.tsx
.../overview/contract-overview-page.client.tsx
.../permissions/ContractPermissionsPage.client.tsx
.../proposals/ContractProposalsPage.client.tsx
.../split/ContractSplitPage.client.tsx
Added optional projectMeta prop to client page components; passed to child components for contextual navigation and redirects.
.../direct-listings/page.tsx
.../english-auctions/page.tsx
.../account-permissions/page.tsx
.../account/page.tsx
.../accounts/page.tsx
.../analytics/page.tsx
.../claim-conditions/page.tsx
.../code/page.tsx
.../cross-chain/page.tsx
.../events/page.tsx
.../explorer/page.tsx
.../modules/page.tsx
.../nfts/page.tsx
.../nfts/[tokenId]/page.tsx
.../overview/page.tsx
.../permissions/page.tsx
.../proposals/page.tsx
.../settings/page.tsx
.../split/page.tsx
.../tokens/page.tsx
.../sources/page.tsx
Simplified all contract-related page components to directly render new shared server components with minimal parameters, removing all contract fetching, validation, and conditional rendering logic.
.../direct-listings/shared-direct-listings-page.tsx
.../english-auctions/shared-english-auctions-page.tsx
.../account-permissions/shared-account-permissions-page.tsx
.../account/shared-account-page.tsx
.../accounts/shared-accounts-page.tsx
.../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
.../modules/shared-modules-page.tsx
.../nfts/shared-nfts-page.tsx
.../nfts/[tokenId]/shared-nfts-token-page.tsx
.../overview/shared-overview-page.tsx
.../permissions/shared-permissions-page.tsx
.../proposals/shared-proposals-page.tsx
.../settings/shared-settings-page.tsx
.../split/shared-split-page.tsx
.../tokens/shared-page.tsx
.../sources/shared-sources-page.tsx
.../shared-layout.tsx
Added new shared server components for each contract page type; handle contract fetching, validation, feature support, and rendering of client/server components based on context and projectMeta.
.../overview/ContractOverviewPage.tsx
.../accounts/AccountsPage.tsx
.../account/AccountPage.tsx
.../nfts/ContractNFTPage.tsx
.../nfts/components/table.tsx
.../overview/components/ContractChecklist.tsx
.../overview/components/Analytics.tsx
.../overview/components/MarketplaceDetails.tsx
.../overview/components/NFTDetails.tsx
.../overview/components/LatestEvents.tsx
.../overview/components/PermissionsTable.tsx
.../overview/components/BuildYourApp.tsx
Added optional projectMeta prop to overview and subcomponents; updated internal links and navigation to use project/team-prefixed URLs where applicable.
.../nfts/[tokenId]/token-id.tsx
.../nfts/components/table.tsx
.../events/events-feed.tsx
.../_components/NFTCards.tsx
.../cross-chain/data-table.tsx
.../accounts/components/accounts-table.tsx
Updated navigation and URL construction to conditionally include project/team slugs from projectMeta for NFT, event, and cross-chain links.
.../_layout/contract-page-layout.client.tsx
.../_layout/contract-page-layout.tsx
.../_layout/primary-dashboard-button.tsx
.../_utils/getContractPageSidebarLinks.ts
Updated layout and sidebar link logic to accept and use projectMeta for path generation and navigation.
.../_components/redirect-contract-overview.client.tsx Updated redirect logic to use projectMeta for constructing contract overview URLs.
.../_utils/getContractFromParams.ts
.../opengraph-image.tsx
Updated contract parameter resolution functions to accept teamId and support new param structure.
.../api/lib/getAuthToken.ts Updated getUserThirdwebClient to accept an explicit teamId parameter for client instantiation.
.../account/contracts/_components/DeployedContractsPage.tsx
.../team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx
.../team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx
.../team/[team_slug]/[project_slug]/(sidebar)/contracts/page.tsx
Added teamSlug and projectSlug props to deployed contracts, assets, and factory components for contextual contract table rendering.
.../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/** Added new route handler pages for all contract features within the team/project context; each page fetches project/team data by slug and renders the corresponding shared component with enriched projectMeta.
.../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx Added new layout component for contract pages within team/project context; handles authentication, team/project resolution, and renders shared contract layout with projectMeta.
.../_utils/contract-page-path.ts Added utility function buildContractPagePath to construct contract page URLs with optional project metadata for team/project context.
.../types.ts Added PublicContractPageParams type alias for structured contract page route parameters.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant RoutePage
    participant API
    participant SharedComponent
    participant ContractComponent

    User->>RoutePage: Access contract page (with team/project slugs)
    RoutePage->>API: Fetch team/project by slug
    API-->>RoutePage: Return team/project (or 404)
    RoutePage->>SharedComponent: Render with contractAddress, chainIdOrSlug, projectMeta
    SharedComponent->>API: Fetch contract info (with projectMeta)
    API-->>SharedComponent: Return contract info
    alt Contract supported
        SharedComponent->>ContractComponent: Render with contract info, projectMeta
    else Not supported
        SharedComponent->>User: Redirect or 404
    end
Loading

Suggested labels

Portal

Suggested reviewers

  • MananTank
  • jnsdls

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: 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 23, 2025 23:04
@MananTank MananTank requested review from a team as code owners May 23, 2025 23:04
@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label May 23, 2025
Copy link
Member Author

MananTank commented May 23, 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 23, 2025 23:04
Copy link

codecov bot commented May 23, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 55.68%. Comparing base (9479d25) to head (1247502).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7152   +/-   ##
=======================================
  Coverage   55.68%   55.68%           
=======================================
  Files         904      904           
  Lines       58340    58340           
  Branches     4107     4107           
=======================================
  Hits        32484    32484           
  Misses      25751    25751           
  Partials      105      105           
Flag Coverage Δ
packages 55.68% <ø> (ø)
🚀 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

github-actions bot commented May 23, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 61.75 KB (0%) 1.3 s (0%) 384 ms (+33.91% 🔺) 1.7 s
thirdweb (cjs) 344.4 KB (0%) 6.9 s (0%) 2.3 s (+9.21% 🔺) 9.2 s
thirdweb (minimal + tree-shaking) 5.69 KB (0%) 114 ms (0%) 84 ms (+274.95% 🔺) 198 ms
thirdweb/chains (tree-shaking) 531 B (0%) 11 ms (0%) 16 ms (+220.66% 🔺) 27 ms
thirdweb/react (minimal + tree-shaking) 19.54 KB (0%) 391 ms (0%) 81 ms (+116.23% 🔺) 472 ms

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: 20

🔭 Outside diff range comments (4)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx (1)

3-8: ⚠️ Potential issue

params should not be typed as a Promise

Next.js’ PageProps shape provides params synchronously – it is already the plain object extracted from the route, not a promise.
Typing it as Promise<…> forces every consumer to await something that is never asynchronous, producing a type-error at compile time and signalling a misleading contract to future maintainers.

-export default async function Page(props: {
-  params: Promise<{
-    contractAddress: string;
-    chain_id: string;
-  }>;
-}) {
-  const params = await props.params;
+export default async function Page(props: {
+  params: {
+    contractAddress: string;
+    chain_id: string;
+  };
+}) {
+  const { params } = props;
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx (1)

4-8: ⚠️ Potential issue

Incorrect Promise typing for params (same issue as settings page)

params is synchronous; typing it as a promise causes type errors and unnecessary await.

-export default async function Page(props: {
-  params: Promise<{
+export default async function Page(props: {
+  params: {
     contractAddress: string;
     chain_id: string;
-  }>;
+  };
 }) {
-  const params = await props.params;
+  const { params } = props;
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx (1)

88-103: ⚠️ Potential issue

Selecting “All” events never updates the UI

eventTypes does not include "all", therefore this guard prevents both
router.push and setSelectedEvent from running when the user chooses “All”.

- if (eventTypes.includes(val)) {
+ if (val === "all" || eventTypes.includes(val)) {

Without this change the dropdown appears selectable but does nothing, which is a UX bug.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx (1)

8-15: 🛠️ Refactor suggestion

params should not be a Promise – mismatched Next.js type

In Next 13/14 route segments, Layout receives props.params as a plain object, not a Promise.
Declaring and await-ing it complicates the type signature and may mask real type errors elsewhere.

-export default async function Layout(props: {
-  params: Promise<{
+export default async function Layout(props: {
+  params: {
     contractAddress: string;
     chain_id: string;
   };
   children: React.ReactNode;
 }) {
-  const params = await props.params;
+  const params = props.params;

Recommend aligning the declaration; TS will then surface issues at compile-time instead of runtime.

♻️ Duplicate comments (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx (1)

4-4: Same import path concern as previous file.

This file has the same deeply nested import path issue for ProjectMeta. Consider the same recommendation to centralize type definitions for better maintainability.

🧹 Nitpick comments (39)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx (1)

5-5: Consider using an absolute import path for better maintainability.

The relative import path is very deep (6 levels) and creates tight coupling between components. This makes the codebase fragile to directory structure changes.

Consider using an absolute import or creating a shared types file:

-import type { ProjectMeta } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/types/project-meta";

Or create a shared types barrel export to reduce the import complexity.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx (1)

4-4: Consider using an absolute import path for better maintainability.

The relative import path is very deep and creates tight coupling. This is the same issue present across multiple files in this PR.

Consider centralizing the ProjectMeta type in a shared location:

-import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/types/project-meta";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx (1)

4-4: Consider using an absolute import path for better maintainability.

This is the same deep relative import path issue seen across multiple files in this PR. Consider creating a shared types module to reduce coupling and improve maintainability.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx (1)

4-4: Consider using a more maintainable import path.

The relative import path with multiple "../" segments could be fragile if the directory structure changes. Consider using an absolute import or creating a shared types barrel export.

For better maintainability, consider:

-import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/app/types/project"; // or similar absolute path

However, since this pattern appears consistent across the codebase refactor, this change can be addressed in a follow-up cleanup.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/page.tsx (1)

1-19: Good refactor, but note parameter inconsistency across shared components.

The extraction to SharedContractSourcesPage is well-implemented and follows the same pattern as other contract pages. However, there's an architectural inconsistency worth noting: this shared component expects teamId: undefined while other shared components (like SharedModulesPage) expect projectMeta: ProjectMeta | undefined.

Consider standardizing the parameter structure across all shared contract page components to use either projectMeta or teamId consistently. This would improve maintainability and reduce confusion.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx (1)

4-4: Consider centralizing type definitions.

The deeply nested import path for ProjectMeta could be improved for maintainability. Consider moving shared types like ProjectMeta to a more central location (e.g., src/types/ or similar) to reduce coupling and improve discoverability.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/modules/page.tsx (1)

10-10: Consider clarifying variable naming for better maintainability.

The variable is named team but you're calling getProject(). Based on the usage where you access team.id and team.slug, it appears the Project object contains team information. For clarity, consider either:

  1. Renaming the variable to project if it represents a project object containing team info
  2. Or updating the comment to clarify that getProject returns team metadata
- const team = await getProject(params.team_slug, params.project_slug);
+ const project = await getProject(params.team_slug, params.project_slug);

- if (!team) {
+ if (!project) {

- teamId: team.id,
- teamSlug: team.slug,
+ teamId: project.teamId, // or project.team.id depending on API structure
+ teamSlug: project.teamSlug, // or project.team.slug depending on API structure

Also applies to: 23-24

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/events/page.tsx (1)

10-10: Consider renaming variable for clarity.

The variable is named team but stores the result of getProject(). While the usage suggests the Project object contains team information, this naming could be confusing for future maintainers.

Consider renaming for clarity:

- const team = await getProject(params.team_slug, params.project_slug);
+ const project = await getProject(params.team_slug, params.project_slug);

And update the references accordingly:

- if (!team) {
+ if (!project) {
    notFound();
  }

  return (
    <SharedEventsPage
      params={{
        contractAddress: params.contractAddress,
        chainIdOrSlug: params.chainIdOrSlug,
        projectMeta: {
          projectSlug: params.project_slug,
-         teamId: team.id,
-         teamSlug: team.slug,
+         teamId: project.teamId, // or project.team.id depending on structure
+         teamSlug: project.teamSlug, // or project.team.slug
        },
      }}
    />
  );
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/code/page.tsx (1)

9-10: Consider renaming variable for clarity.

The variable team actually contains project data from getProject(). Consider renaming it to project for better code readability.

- const team = await getProject(params.team_slug, params.project_slug);
+ const project = await getProject(params.team_slug, params.project_slug);

And update the reference on line 23:

- teamId: team.id,
+ teamId: project.id,

And line 24:

- teamSlug: team.slug,
+ teamSlug: project.slug,
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account-permissions/page.tsx (1)

3-3: Consider using absolute imports to improve maintainability.

The relative import path ../../../../../../../(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page is very long and brittle to refactoring. Consider using absolute imports or path aliases.

-import { SharedContractAccountPermissionsPage } from "../../../../../../../(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page";
+import { SharedContractAccountPermissionsPage } from "@/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page";
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx (1)

3-3: Consider using absolute imports to improve maintainability.

The relative import path is very long and brittle to refactoring. Consider using absolute imports or path aliases for better maintainability.

-import { SharedNFTPage } from "../../../../../../../(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page";
+import { SharedNFTPage } from "@/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page";
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/[tokenId]/page.tsx (2)

14-14: Fix confusing variable naming

The variable name team is misleading since getProject() returns a project object, not a team. This could cause confusion for future developers.

- const team = await getProject(params.team_slug, params.project_slug);
+ const project = await getProject(params.team_slug, params.project_slug);

- if (!team) {
+ if (!project) {

Also applies to: 16-16


26-30: Update variable reference in ProjectMeta construction

Following the variable naming fix above, update the reference in the projectMeta object.

projectMeta: {
  projectSlug: params.project_slug,
- teamId: team.id,
- teamSlug: team.slug,
+ teamId: project.id,
+ teamSlug: project.slug,
},
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/settings/page.tsx (1)

3-3: Consider refactoring the long import path for maintainability.

The import path ../../../../../../../(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page is quite long and fragile. Consider using a path alias or moving shared components to a more accessible location.

// Consider using a path alias like:
import { SharedContractSettingsPage } from "@/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page";
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (1)

3-3: Same import path maintainability concern.

Similar to other files in this refactor, consider using path aliases for the long relative import.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx (2)

1-3: Replace brittle deep-relative import with an absolute/alias path

Nine “../” segments are easy to get wrong (and they already differ from the depth used in neighbouring pages).
Using the existing @/ alias (or introducing one) avoids future breakage when folders move.

-import { SharedContractOverviewPage } from "../../../../../../(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page";
+import { SharedContractOverviewPage } from "@/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page";

16-29: Memoise the team lookup to avoid N+1 requests across sibling pages

Every contract sub-page repeats:

const team = await getTeamBySlug(params.team_slug);

When a user navigates between pages, the same network request is made again.
Wrapping getTeamBySlug with cache() from React 18 (or re-exporting a cached variant) will give a free in-memory response and speed up navigation:

// in @/api/team.ts
-import { getAuthToken } from "./auth";
+import { getAuthToken } from "./auth";
+import { cache } from "react";

-export async function getTeamBySlug(slug: string) {
+export const getTeamBySlug = cache(async (slug: string) => {
   ...
-}
+});
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/english-auctions/page.tsx (1)

6-10: Consistent handling of params

Same remark as in the claim-conditions page: if params is not actually a Promise here, drop the await and adjust the type.
Keeping the signature consistent across the new team/project pages will avoid confusion.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/claim-conditions/page.tsx (1)

10-10: Consider renaming the variable for clarity.

The variable is named team but the getProject API call returns project data according to the function signature. Consider renaming it to project for consistency:

-  const team = await getProject(params.team_slug, params.project_slug);
+  const project = await getProject(params.team_slug, params.project_slug);

And update the subsequent references accordingly.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx (1)

14-14: Consider using an absolute import path.

The relative import path is quite long and brittle. Consider using an absolute import if the types are commonly used across the dashboard:

-import type { ProjectMeta } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/types/project"; // or similar absolute path
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx (1)

10-10: Consider renaming the variable for clarity.

Same issue as in the claim-conditions page - the variable is named team but contains project data. For consistency and clarity:

-  const team = await getProject(params.team_slug, params.project_slug);
+  const project = await getProject(params.team_slug, params.project_slug);

And update lines 23-24 accordingly.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-table.tsx (2)

19-19: Extremely long relative import path – consider using a path alias

The multi-../ path is brittle; a single directory move will break the import and makes the location of ProjectMeta non-obvious. Add a tsconfig.json/jest path alias (e.g. @/types/ProjectMeta) so consumers can import it concisely and safely.


99-107: onRowClick URL building duplicates routing logic

Hard-coding the paths in multiple components risks divergence from the canonical router helpers. Consider centralising URL creation in useDashboardRouter (e.g. router.toContractAccount(projectMeta, chainSlug, row.account)) to avoid future inconsistencies and to automatically encode path params.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx (1)

1-1: Remove empty import – it produces an unused-import lint error

import {} from "next/navigation"; imports nothing and is unnecessary.

-import {} from "next/navigation";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)

30-30: Optimize useEffect dependencies for better performance

The current dependency array [router, props] is too broad. The props object reference changes on every render, causing unnecessary effect re-runs.

Consider destructuring the specific props needed in the dependency array:

-  }, [router, props]);
+  }, [router, props.contract.chain.id, props.contract.address, props.projectMeta]);

This ensures the effect only runs when the actual values change, not when the props object reference changes.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx (1)

16-28: Optimize performance with parallel data fetching.

Unlike other shared components in this PR, this implementation fetches the account sequentially after contract info rather than in parallel. This could impact performance.

Consider using Promise.all for parallel fetching to match the pattern used in other shared components:

-  const info = await getContractPageParamsInfo({
-    contractAddress: params.contractAddress,
-    chainIdOrSlug: params.chainIdOrSlug,
-    teamId: params.projectMeta?.teamId,
-  });
-
-  if (!info) {
-    notFound();
-  }
-
-  const twAccount = await getRawAccount();
+  const [twAccount, info] = await Promise.all([
+    getRawAccount(),
+    getContractPageParamsInfo({
+      contractAddress: params.contractAddress,
+      chainIdOrSlug: params.chainIdOrSlug,
+      teamId: params.projectMeta?.teamId,
+    }),
+  ]);
+
+  if (!info) {
+    notFound();
+  }

This matches the performance optimization pattern used in shared-direct-listings-page.tsx (lines 17-24).

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx (1)

28-28: Use consistent variable naming across shared components.

The variable twAccount should be named account for consistency with other shared contract components.

-  const twAccount = await getRawAccount();
+  const account = await getRawAccount();

And update the references accordingly:

-        isLoggedIn={!!twAccount}
+        isLoggedIn={!!account}
-    <ContractSplitPage contract={clientContract} isLoggedIn={!!twAccount} />
+    <ContractSplitPage contract={clientContract} isLoggedIn={!!account} />
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx (1)

8-21: Parameter structure inconsistency across shared components.

The parameter structure here differs from SharedContractTokensPage - this component takes projectMeta as a parameter and extracts teamId from it, while the tokens shared page takes teamId directly. Consider standardizing the parameter structure across all shared components for consistency.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (2)

1-3: Import path with nested dynamic segments is fragile

The relative path to types.ts walks through several dynamic route folders.
Changes in folder depth or renaming any route segment will silently break the import and TypeScript will not resolve it until build time.

-import type { ProjectMeta } from "../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+// ✅ consider using the path alias already configured for app code, e.g.:
+import type { ProjectMeta } from "@/app/types/project-meta";

Using a ts-config path alias (e.g. @/app/...) improves resiliency and readability.


57-61: Silent swallow of PublishedBy errors loses debugging signal

ErrorBoundary with fallback={null} hides all publisher-related errors without
logging, making production issues hard to trace.

-<ErrorBoundary fallback={null}>
+<ErrorBoundary
+  fallback={null}
+  onError={(err) => {
+    // eslint-disable-next-line no-console -- server-only diagnostic
+    console.error("[ContractOverview] PublishedBy failed:", err);
+  }}
+>

Adding a minimal onError callback (or Sentry capture) preserves observability without breaking the end-user experience.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1)

41-45: Minor optimisation: parallelise account and metadata fetch

getAuthTokenWalletAddress and getRawAccount are already parallelised, but
getContractPageMetadata (non-localhost branch) could also be added to the
Promise.all above to save one round-trip latency.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx (2)

28-35: Nit: Destructuring names mismatch hampers readability

getSelectors returns { writeFnSelectorToName, eventSelectorToName } but the
result is unpacked into variables with the same names; the “Record” suffix is
added only at the prop level. Consider harmonising names:

-    { eventSelectorToName, writeFnSelectorToName },
+    { eventSelectorToName: eventSelectorToNameRecord,
+      writeFnSelectorToName: writeFnSelectorToNameRecord },

and pass the variables with identical names.
This avoids accidental shadowing when the component grows.


53-70: Guard against missing name in ABI items

Some ABI entries (e.g. fallback / receive functions) lack name; current code
would assign undefined, producing a selector→undefined mapping.

-        writeFnSelectorToName[toFunctionSelector(item)] = item.name;
+        if (item.name) {
+          writeFnSelectorToName[toFunctionSelector(item)] = item.name;
+        }

The same applies to events.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx (1)

54-57: URL construction logic duplicated & fragile – extract a helper

contractRootPath is recomputed in multiple places (EventsFeed, EventsFeedItem,
MarketplaceDetails, etc.).
Centralising this logic will:

  1. Prevent subtle mismatches (/contract vs. empty string).
  2. Reduce boilerplate.

Example:

// utils/paths.ts
export const getContractRoot = (meta?: ProjectMeta) =>
  meta ? `/team/${meta.teamSlug}/${meta.projectSlug}/contract` : "";

Then:

-const contractRootPath = projectMeta
-  ? `/team/${projectMeta.teamSlug}/${projectMeta.projectSlug}/contract`
-  : "";
+const contractRootPath = getContractRoot(projectMeta);

Also applies to: 191-194

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx (1)

300-308: Hard-coded URL pieces – rely on extracted helper

See previous comment: replace inline interpolation with the shared
getContractRoot() helper to keep path generation consistent.

-const directListingsHref = `${contractRootPath}/${chainSlug}/${contractAddress}/direct-listings`;
-const englishAuctionsHref = `${contractRootPath}/${chainSlug}/${contractAddress}/english-auctions`;
+const base = `${getContractRoot(projectMeta)}/${chainSlug}/${contractAddress}`;
+const directListingsHref = `${base}/direct-listings`;
+const englishAuctionsHref = `${base}/english-auctions`;
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (1)

196-210: Minor copy edit – double space & slug vs chain-ID wording

The fallback metadata description currently renders with two spaces ("contract on") and always says “Chain ID” even when a slug such as polygon is supplied:

description: `View tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract  on ${cleanedChainName}`;
...
description: `View tokens, transactions, balances, source code, and analytics for the smart contract  on Chain ID ${params.chainIdOrSlug}`,

Consider tightening the string and conditionally wording the identifier:

-  description = `View tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract  on ${cleanedChainName}`;
+  description = `View tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}.`;

...

-  description: `View tokens, transactions, balances, source code, and analytics for the smart contract  on Chain ID ${params.chainIdOrSlug}`,
+  description: `View tokens, transactions, balances, source code, and analytics for this smart contract on ${params.chainIdOrSlug}.`,

A tiny tweak, but it improves the professionalism of SEO snippets.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (3)

129-170: Skip the home chain before firing 9 extra RPC calls

defaultChains always includes the current chain, yet it is filtered after the
Promise.all, meaning we still perform an unnecessary eth_getCode on the chain we
already have data for.

-    await Promise.all(
-      defaultChains.map(async (c) => {
+    await Promise.all(
+      defaultChains
+        .filter((c) => c !== serverContract.chain.id) // avoid redundant call
+        .map(async (c) => {

Small change, but it saves one network round-trip per request and reduces noise in
RPC metrics.


60-68: Suppressing all errors can hide genuine connectivity issues

The empty catch {} around getDeployedCloneFactoryContract swallows
network/ABI errors that might explain missing data later on.
At minimum, log a warning with console.warn (server side) or return a typed
Result object so callers can act accordingly.


181-185: Early return bypasses fetch-error handling

When fetchPublishedContractsFromDeploy fails we fall back to the
“NoCrossChainPrompt” without differentiating between “metadata not found”
and “network error / rate limit”. Users may mistake transient errors for an
absence of cross-chain capability.

Consider distinguishing:

} catch (e) {
  logger.error(e);
  return <ErrorState message="Unable to fetch deploy metadata. Please retry." />;
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3489ece and 1f6e73a.

📒 Files selected for processing (107)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/ContractDirectListingsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageSidebarLinks.ts (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-table.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/opengraph-image.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx (7 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]/overview/components/BuildYourApp.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/LatestEvents.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx (11 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/NFTDetails.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/PermissionsTable.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/contract-overview-page.client.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/ContractProposalsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/ContractSplitPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/account/contracts/_components/DeployedContractsPage.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/api/lib/getAuthToken.ts (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/contracts/page.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/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/english-auctions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account-permissions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/accounts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/analytics/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/claim-conditions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/code/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/cross-chain/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/events/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/modules/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/[tokenId]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/permissions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/proposals/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/settings/page.tsx (1 hunks)
⛔ Files not processed due to max files limit (9)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/sources/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/split/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/tokens/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts
  • apps/dashboard/src/components/contract-components/tables/cells.tsx
  • apps/dashboard/src/components/contract-components/tables/contract-table.stories.tsx
  • apps/dashboard/src/components/contract-components/tables/contract-table.tsx
  • apps/dashboard/src/components/smart-wallets/AccountFactories/factory-contracts.tsx
🧰 Additional context used
🧠 Learnings (8)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/permissions/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/analytics/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/code/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
🧬 Code Graph Analysis (77)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/opengraph-image.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
  • getContractPageParamsInfo (8-46)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.client.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/ContractDirectListingsPage.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx (1)
  • SharedContractSplitPage (9-49)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx (1)
  • SharedContractAccountPermissionsPage (8-45)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/team.ts (1)
  • getTeamBySlug (11-30)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx (1)
  • SharedDirectListingsPage (9-54)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/ContractSplitPage.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx (1)
  • SharedContractSourcesPage (5-19)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/claim-conditions/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/projects.ts (1)
  • getProject (29-48)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (1)
  • SharedClaimConditionsPage (10-73)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/permissions/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/projects.ts (1)
  • getProject (29-48)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1)
  • SharedPermissionsPage (9-54)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1)
  • SharedPermissionsPage (9-54)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (1)
  • SharedClaimConditionsPage (10-73)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/ContractProposalsPage.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account-permissions/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/team.ts (1)
  • getTeamBySlug (11-30)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx (1)
  • SharedContractAccountPermissionsPage (8-45)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/BuildYourApp.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (1)
  • SharedContractSettingsPage (10-56)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.tsx (1)
  • AccountsPage (17-52)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx (1)
  • SharedNFTPage (10-62)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx (1)
  • SharedModulesPage (10-55)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx (1)
  • SharedAccountsPage (9-57)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx (1)
  • SharedContractAccountPage (9-59)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
  • getContractPageParamsInfo (8-46)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (1)
  • SharedContractOverviewPage (10-64)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx (1)
  • SharedContractProposalsPage (9-48)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-table.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/events/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/projects.ts (1)
  • getProject (29-48)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx (1)
  • SharedEventsPage (6-30)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1)
  • SharedNFTTokenPage (11-79)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/PermissionsTable.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
  • RedirectToContractOverview (9-33)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/proposals/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/team.ts (1)
  • getTeamBySlug (11-30)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx (1)
  • SharedContractProposalsPage (9-48)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/english-auctions/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/team.ts (1)
  • getTeamBySlug (11-30)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx (1)
  • SharedEnglishAuctionsPage (9-53)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/team.ts (1)
  • getTeamBySlug (11-30)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (1)
  • SharedContractOverviewPage (10-64)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx (1)
  • SharedEventsPage (6-30)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx (1)
  • SharedCodePage (8-47)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx (5)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
  • getContractPageParamsInfo (8-46)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/ContractProposalsPage.client.tsx (1)
  • ContractProposalsPageClient (10-40)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageMetadata.ts (1)
  • getContractPageMetadata (30-32)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx (1)
  • SharedExplorerPage (9-53)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx (4)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
  • getContractPageParamsInfo (8-46)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx (1)
  • AccountSignersClient (10-34)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageMetadata.ts (1)
  • getContractPageMetadata (30-32)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/analytics/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/projects.ts (1)
  • getProject (29-48)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx (1)
  • SharedAnalyticsPage (10-51)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx (1)
  • SharedDirectListingsPage (9-54)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/code/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/projects.ts (1)
  • getProject (29-48)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx (1)
  • SharedCodePage (8-47)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/api/lib/getAuthToken.ts (1)
apps/dashboard/src/@/constants/thirdweb-client.client.ts (1)
  • getClientThirdwebClient (3-11)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/contract-overview-page.client.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/modules/page.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx (1)
  • SharedModulesPage (10-55)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
apps/dashboard/src/app/(app)/api/lib/getAuthToken.ts (1)
  • getUserThirdwebClient (32-51)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/NFTDetails.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx (1)
  • SharedContractTokensPage (12-50)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx (1)
  • NftsOwned (14-51)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/LatestEvents.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/@3rdweb-sdk/react/hooks/useActivity.ts (1)
  • useActivity (16-55)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx (6)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
  • getContractPageParamsInfo (8-46)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx (1)
  • ContractEditModulesPageClient (10-40)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageMetadata.ts (1)
  • getContractPageMetadata (30-32)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts (1)
  • redirectToContractLandingPage (5-18)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx (1)
  • SharedEnglishAuctionsPage (9-53)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/[tokenId]/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/projects.ts (1)
  • getProject (29-48)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1)
  • SharedNFTTokenPage (11-79)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (4)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
  • getContractPageParamsInfo (8-46)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageMetadata.ts (1)
  • getContractPageMetadata (30-32)
apps/dashboard/src/constants/addresses.ts (1)
  • DEFAULT_FEE_RECIPIENT (7-8)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageSidebarLinks.ts (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/team.ts (1)
  • getTeamBySlug (11-30)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx (1)
  • SharedContractAccountPage (9-59)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/accounts/page.tsx (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectContractPageParams (1-6)
apps/dashboard/src/@/api/team.ts (1)
  • getTeamBySlug (11-30)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx (1)
  • SharedAccountsPage (9-57)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx (5)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
  • getContractPageParamsInfo (8-46)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/ContractSplitPage.client.tsx (1)
  • ContractSplitPageClient (10-40)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageMetadata.ts (1)
  • getContractPageMetadata (30-32)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx (5)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
  • getContractPageParamsInfo (8-46)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx (1)
  • ContractEnglishAuctionsPageClient (10-41)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageMetadata.ts (1)
  • getContractPageMetadata (30-32)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (6)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (1)
  • getContractPageParamsInfo (8-46)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageMetadata.ts (1)
  • getContractPageMetadata (30-32)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx (1)
  • ClaimConditionsClient (10-48)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts (1)
  • redirectToContractLandingPage (5-18)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts (1)
  • ProjectMeta (8-12)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (146)
apps/dashboard/src/app/(app)/api/lib/getAuthToken.ts (1)

32-51: LGTM! Good API design improvement.

The function signature change to accept a parameter object with optional teamId follows good practices and aligns well with the project-scoped functionality being introduced. The prioritization logic correctly handles explicit teamId parameters while preserving the existing cookie-based fallback behavior.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.client.tsx (2)

5-5: LGTM! Proper type import.

The import of ProjectMeta type uses the correct relative path and follows TypeScript best practices.


14-14: LGTM! Clean prop threading.

The addition of the optional projectMeta prop and its pass-through to the child component is implemented correctly and follows the established pattern for project-scoped functionality.

Also applies to: 28-28

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/contracts/page.tsx (1)

45-46: LGTM! Proper prop addition.

The addition of teamSlug and projectSlug props to DeployedContractsPage correctly uses the already available parameters and follows the established pattern for project-scoped functionality.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/opengraph-image.tsx (1)

24-28: LGTM! Correct function signature update.

The update to explicitly construct the parameter object with chainIdOrSlug and teamId: undefined correctly matches the new function signature shown in the relevant code snippets. Setting teamId to undefined is appropriate for this route context which doesn't have project scope.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx (1)

11-11: LGTM! Consistent project metadata integration.

The addition of the optional projectMeta prop and its propagation to NFTCards follows the established pattern for project-scoped routing support. The type safety is maintained with proper TypeScript annotations.

Also applies to: 17-17, 30-30

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx (1)

13-13: LGTM! Proper project metadata propagation.

The addition of the projectMeta prop and its forwarding to RedirectToContractOverview enables project-scoped routing when claim conditions are unsupported. The conditional rendering logic correctly maintains the redirect behavior while adding project context.

Also applies to: 32-37

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx (1)

12-12: LGTM! Consistent project metadata integration.

The projectMeta prop addition and its propagation to RedirectToContractOverview maintains consistency with the broader architectural pattern. The conditional rendering logic correctly handles unsupported account permissions while preserving project context during redirects.

Also applies to: 25-30

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/ContractSplitPage.client.tsx (2)

13-13: LGTM! Consistent project metadata integration.

The projectMeta prop addition and its propagation to RedirectToContractOverview follows the established pattern. The conditional rendering correctly handles unsupported split contracts while maintaining project context.

Also applies to: 26-31


34-39:

❌ Incorrect review comment

Consider passing projectMeta to ContractSplitPage if needed.

The ContractSplitPage component doesn't receive the projectMeta prop. If this component contains links or navigation that should be project-scoped, it may need the project context.

Please verify if ContractSplitPage needs project context for any internal navigation or links:


🏁 Script executed:

#!/bin/bash
# Description: Check if ContractSplitPage component uses any navigation or links that might benefit from project context

# Search for navigation-related patterns in ContractSplitPage
ast-grep --pattern 'export $_ ContractSplitPage($_) {
  $$$
}'

# Also search for Link components or router usage
rg -A 10 -B 5 "Link|router|href" apps/dashboard/src/app/\(app\)/\(dashboard\)/\(chain\)/\[chain_id\]/\[contractAddress\]/split/ContractSplitPage.tsx || echo "ContractSplitPage.tsx not found at expected location"

# Search for any file with ContractSplitPage
fd ContractSplitPage.tsx

Length of output: 455


🏁 Script executed:

#!/bin/bash
# Locate ContractSplitPage.tsx and inspect for navigation-related code
FILE=$(fd ContractSplitPage.tsx | head -n1)
echo "Inspecting file: $FILE"

echo "- Checking for Link imports"
rg -n "import.*Link" "$FILE" || echo "No Link imports found"

echo "- Checking for next/link imports"
rg -n "import.*next/link" "$FILE" || echo "No next/link imports found"

echo "- Checking for href attributes"
rg -n "href=" "$FILE" || echo "No href attributes found"

echo "- Checking for router usage"
rg -n "router\." "$FILE" || echo "No router usage found"

Length of output: 1429


Ignore passing projectMeta to ContractSplitPage
No link, router or navigation logic exists in ContractSplitPage.tsx, so there’s currently no need for a project context prop.

Likely an incorrect or invalid review comment.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx (2)

13-13: Well-implemented prop addition.

The optional projectMeta prop is properly typed and aligns with the component's dual usage in both project-scoped and legacy routing contexts.


26-31: Correct implementation of project-aware redirect.

The projectMeta prop is properly passed to RedirectToContractOverview, enabling project-scoped URL generation when redirecting non-modular core contracts. The conditional logic flow remains intact while adding the necessary project context.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/ContractDirectListingsPage.client.tsx (2)

4-4: Consistent implementation with project metadata support.

The import and prop addition follow the same pattern as other components in this refactor, maintaining consistency across the codebase. The optional projectMeta typing is appropriate for dual-context usage.

Also applies to: 13-13


26-31: Proper project-aware redirect for unsupported direct listings.

The redirect logic correctly passes projectMeta to enable project-scoped URL generation when direct listings are not supported. The conditional check using isDirectListingSupported is appropriate for this marketplace component.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/page.tsx (2)

1-1: Excellent page simplification through shared component delegation.

The refactoring to use SharedContractSplitPage effectively centralizes complex contract handling logic while simplifying the page component. This approach reduces code duplication and improves maintainability across the contract dashboard.

Also applies to: 11-17


15-15: Appropriate explicit projectMeta handling for legacy route.

Setting projectMeta: undefined is correct for this legacy route context, clearly indicating that this page operates without project scope. This explicit handling helps maintain clarity between legacy and project-scoped routing paths.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx (1)

1-1: Consistent page simplification following established pattern.

The refactoring matches the pattern established in other contract pages, delegating complex logic to SharedContractAccountPermissionsPage while maintaining appropriate parameter mapping and explicit projectMeta: undefined for the legacy route context.

Also applies to: 10-18

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/ContractProposalsPage.client.tsx (3)

4-4: LGTM: Import path is correct for ProjectMeta type.

The relative import path correctly references the ProjectMeta type definition from the team/project contract types.


13-13: LGTM: Optional projectMeta prop follows the established pattern.

The addition of the optional projectMeta prop is consistent with the broader refactoring effort to support project-scoped routing throughout the dashboard.


26-31: LGTM: Proper propagation of projectMeta to child component.

The projectMeta prop is correctly passed to the RedirectToContractOverview component, ensuring consistent project context for URL construction and navigation.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/BuildYourApp.tsx (3)

4-4: LGTM: Import path is correct for ProjectMeta type.

The relative import path correctly references the ProjectMeta type definition.


10-14: LGTM: Clean implementation of project-scoped URL construction.

The conditional logic properly constructs the contractRootPath when projectMeta is available, enabling project-scoped URLs while maintaining backward compatibility.


26-26: LGTM: Proper usage of contractRootPath in href construction.

The contractRootPath is correctly prepended to the URL, enabling proper navigation within the team/project context when available.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx (3)

9-9: LGTM: Import path is correct for ProjectMeta type.

The relative import path correctly references the ProjectMeta type definition.


20-20: LGTM: Clean addition of projectMeta prop.

The projectMeta prop is properly added to the component interface and destructured, following the established pattern for project-scoped routing support.

Also applies to: 35-35


50-50: LGTM: Improved prop passing to PrimaryDashboardButton.

The changes correctly:

  • Add projectMeta prop for project context
  • Use contract.client instead of a separate client prop, which is cleaner and more consistent

Also applies to: 59-59

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx (3)

4-4: LGTM: Import path is correct for ProjectMeta type.

The relative import path correctly references the ProjectMeta type definition from the team/project contract types.


15-15: LGTM: Optional projectMeta prop follows the established pattern.

The addition of the optional projectMeta prop is consistent with the broader refactoring effort to support project-scoped routing throughout the dashboard.


31-36: LGTM: Proper propagation of projectMeta to child components.

The projectMeta prop is correctly passed to both:

  • RedirectToContractOverview for proper URL construction during redirects
  • TokenIdPage for consistent project context throughout the component tree

Also applies to: 46-46

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx (1)

1-19: LGTM! Clean refactor to shared component pattern.

The refactor successfully extracts complex contract fetching and validation logic to SharedModulesPage, making this page component much simpler and more maintainable. The parameter mapping from chain_id to chainIdOrSlug is consistent with the shared component's interface.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx (3)

5-7: Clean type import updates for project-scoped routing.

The import changes correctly replace the ThirdwebClient dependency with ProjectMeta to support team/project-scoped navigation.


19-19: Props updated to support project metadata.

The prop change from client: ThirdwebClient to projectMeta: ProjectMeta | undefined aligns with the project-scoped routing refactor across the dashboard.


43-43: Correct integration with sidebar link generation.

Passing projectMeta to getContractPageSidebarLinks ensures that sidebar navigation URLs are properly prefixed with team/project context when available.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx (1)

1-31: Well-implemented shared component following established patterns.

The SharedEventsPage component correctly implements the shared component pattern with proper error handling and parameter structure. It uses projectMeta parameter (consistent with SharedModulesPage), handles the not-found case appropriately, and passes the necessary props to EventsFeed.

The component properly extracts teamId from projectMeta when calling getContractPageParamsInfo, ensuring team-scoped contract resolution works correctly.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/proposals/page.tsx (1)

1-29: LGTM! Clean implementation following the established pattern.

This page component correctly implements the team/project-scoped contract proposals functionality by:

  • Properly awaiting the params Promise (consistent with Next.js server components)
  • Fetching team data and handling not found cases appropriately
  • Constructing the projectMeta object with the correct team and project information
  • Delegating rendering to the shared component
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx (1)

5-5: LGTM! Proper prop threading for project-scoped functionality.

The changes correctly implement support for the optional projectMeta prop by:

  • Adding the appropriate import for the ProjectMeta type
  • Including the prop in the component interface as optional
  • Passing it through to both RedirectToContractOverview and AccountPage components

This follows the consistent pattern established across other similar client components in the dashboard.

Also applies to: 15-15, 28-33, 42-42

apps/dashboard/src/app/(app)/account/contracts/_components/DeployedContractsPage.tsx (1)

15-16: LGTM! Clean prop threading for team/project context.

The addition of teamSlug and projectSlug props is implemented correctly:

  • Props are consistently added to both the main and async component interfaces
  • They are properly passed through to the ContractTable component
  • No breaking changes introduced

This enables the component to work within the team/project-scoped routing structure.

Also applies to: 44-45, 63-64

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx (1)

1-19: LGTM! Clean refactoring following separation of concerns.

This refactoring successfully delegates all contract-specific logic to the SharedNFTPage component, simplifying the page component to focus only on parameter extraction. The pattern of passing projectMeta: undefined is consistent with the dashboard routes not having project context yet, while the shared component can handle both scenarios.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx (2)

10-14: LGTM! Proper addition of projectMeta prop.

The projectMeta prop is correctly typed as optional and follows the established pattern for enabling project-scoped routing.


26-31: LGTM! Correct prop forwarding for project-scoped redirects.

The RedirectToContractOverview component now receives the projectMeta prop, enabling it to redirect to the appropriate project-scoped URL when applicable.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx (1)

1-19: LGTM! Consistent refactoring pattern.

This change follows the same clean refactoring pattern as other contract pages, successfully delegating complex logic to the SharedCodePage component while maintaining proper parameter passing. The projectMeta: undefined is appropriate for dashboard routes.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx (2)

10-14: LGTM! Consistent prop addition pattern.

The projectMeta prop addition follows the established pattern and is properly typed as optional.


28-33: LGTM! Complete prop forwarding for project-scoped functionality.

Both the RedirectToContractOverview and ContractNFTPage components now correctly receive the projectMeta prop, enabling proper project-scoped routing and UI context throughout the NFT page flow.

Also applies to: 36-44

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/contract-overview-page.client.tsx (1)

4-4: LGTM! Clean implementation of project metadata propagation.

The changes properly introduce the ProjectMeta prop with correct typing, optional handling, and clean prop threading through the component hierarchy.

Also applies to: 12-12, 14-14, 30-30

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.tsx (1)

4-4: LGTM! Consistent implementation pattern.

The changes follow the same clean pattern as other components, properly integrating project metadata into the NFT page with correct typing and prop propagation.

Also applies to: 20-20, 28-28, 113-113

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx (1)

4-4: LGTM! Proper prop threading to child components.

The implementation correctly passes the projectMeta to both the redirect and main page components, maintaining consistency with the overall refactoring pattern.

Also applies to: 13-13, 26-31, 35-40

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/modules/page.tsx (1)

6-14: LGTM! Proper async handling and error management.

The implementation correctly handles the async params, fetches project data, and uses notFound() for missing resources, which is the appropriate 404 handling pattern for Next.js.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx (1)

1-19: Clean shared component implementation following established patterns.

This shared server component correctly implements the pattern seen across the PR:

  • Proper contract info fetching with error handling
  • Clean separation between data fetching and rendering logic
  • Consistent parameter structure with optional team context
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/events/page.tsx (1)

6-29: Good implementation of project-scoped page pattern.

The implementation correctly:

  • Awaits the params Promise (consistent with Next.js behavior noted in learnings)
  • Implements proper error handling for missing projects
  • Follows the established pattern for passing projectMeta to shared components
  • Maintains consistency with other project-scoped pages in the PR
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx (1)

1-19: Excellent refactoring to centralize logic in shared components.

This simplification successfully:

  • Delegates complex contract info fetching and validation to SharedAnalyticsPage
  • Maintains the same page interface while reducing duplication
  • Correctly passes undefined for projectMeta in non-project context
  • Follows the consistent pattern established across other contract pages

This refactor improves maintainability by centralizing the complex analytics logic.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1)

6-29: Consistent implementation with clear variable naming.

This project-scoped page correctly:

  • Uses appropriate API call (getTeamBySlug) for fetching team data
  • Maintains clear variable naming (team for team data)
  • Implements consistent error handling and parameter passing patterns
  • Properly awaits the params Promise as expected in Next.js

The implementation is consistent with the established pattern across other project-scoped pages in this PR.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx (1)

1-20: LGTM! Clean refactoring to shared component pattern.

The simplification of this page by delegating logic to SharedContractTokensPage is a good architectural improvement. The async/await pattern for params is correct for Next.js server components, and passing undefined for teamId is appropriate for the non-team scoped route.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (2)

8-12: LGTM! Parameter updates support team-scoped functionality.

The renaming of chain_id to chainIdOrSlug improves consistency, and the addition of the optional teamId parameter correctly supports the team-scoped contract functionality.


35-37: LGTM! Correct usage of updated getUserThirdwebClient API.

The function call correctly passes the teamId parameter in the expected object format, matching the updated getUserThirdwebClient function signature.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/code/page.tsx (2)

12-14: LGTM! Proper error handling for missing projects.

The notFound() call correctly handles cases where the project doesn't exist or the user doesn't have access.


17-27: LGTM! Correct projectMeta construction and prop passing.

The projectMeta object is properly constructed with all required fields and correctly passed to the SharedCodePage component, enabling team/project-scoped functionality.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.tsx (3)

6-6: LGTM! Correct import of ProjectMeta type.

The import path correctly references the ProjectMeta type definition from the team/project contract types.


16-16: LGTM! Appropriate addition of projectMeta prop.

The optional projectMeta prop addition enables team/project-scoped functionality while maintaining backward compatibility.


50-54: LGTM! Correct prop forwarding to NftsOwned component.

The projectMeta prop is properly passed to the NftsOwned component, enabling project-scoped NFT functionality as shown in the relevant code snippets.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx (2)

8-8: LGTM: Clean import of ProjectMeta type.

The import path correctly references the types file for the project-scoped contract pages.


16-16: LGTM: Proper projectMeta prop integration.

The implementation correctly:

  • Adds optional projectMeta prop to the interface
  • Constructs contractRootPath conditionally based on projectMeta presence
  • Defaults to empty string when projectMeta is undefined
  • Uses the path consistently in explorerHref construction

This follows the expected pattern for enabling project-scoped URLs.

Also applies to: 21-30

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account-permissions/page.tsx (1)

1-1:

✅ Verification successful

Inconsistent data fetching approach compared to similar pages.

This page uses getTeamBySlug to fetch team data, but the route structure suggests it should be fetching project-specific data. Compare with the NFTs page which uses getProject(params.team_slug, params.project_slug) for the same route pattern.

Let me verify the correct API to use for project-scoped pages:

Also applies to: 10-10


🏁 Script executed:

#!/bin/bash
# Check which API function is used in other similar project-scoped contract pages
rg -A 5 "getTeamBySlug|getProject" apps/dashboard/src/app/\(app\)/team/\[team_slug\]/\[project_slug\]/contract/

Length of output: 42668


No change needed for data fetching approach

The account-permissions page aligns with a group of contract subpages (split, tokens, sources, proposals, settings, account, accounts, english-auctions, direct-listings) that intentionally use getTeamBySlug. Pages that require project-scoped metadata (events, permissions, NFTs, modules, explorer, cross-chain, code, analytics, claim-conditions) use getProject. This split is by design, so no update is required here.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx (1)

1-1: LGTM: Clean architectural improvement.

The simplification to delegate to SharedExplorerPage is a good architectural change that centralizes complex contract data fetching and conditional rendering logic. Setting projectMeta: undefined is appropriate for the non-project-scoped route.

Also applies to: 11-17

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx (1)

68-69: LGTM: Clean propagation of team/project context

The changes correctly propagate teamSlug and projectSlug through the component hierarchy to enable team/project-scoped URLs in the ContractTable component. The implementation is clean and follows the established pattern.

Also applies to: 97-98, 116-117

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/NFTDetails.tsx (1)

10-10: LGTM: Correct implementation of conditional URL construction

The changes properly implement team/project context support by:

  • Adding optional projectMeta prop with correct typing
  • Conditionally constructing URLs with team/project prefix when context is available
  • Maintaining backward compatibility by falling back to original behavior
  • Correctly propagating the context to child components

Also applies to: 18-18, 26-26, 28-32, 68-68

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/[tokenId]/page.tsx (1)

1-34: LGTM: Follows established pattern correctly

The page component correctly implements the pattern of:

  • Fetching project data using the API
  • Handling missing projects with 404 responses
  • Delegating rendering to shared components with enriched metadata
  • Constructing proper ProjectMeta object for team/project context
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/PermissionsTable.tsx (1)

22-22: LGTM: Consistent implementation of project context

The changes correctly follow the established pattern by:

  • Adding optional projectMeta prop with proper typing
  • Conditionally constructing the base path for permissions URLs
  • Maintaining backward compatibility when project context is not available
  • Using the constructed path consistently in the component

The implementation is consistent with similar changes in other overview components.

Also applies to: 28-28, 30-32, 62-62

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/settings/page.tsx (1)

1-25: LGTM! Clean implementation following the new pattern.

The implementation correctly follows the bridge pattern for team/project scoped routing:

  • Properly awaits params (following Next.js best practices)
  • Fetches team data with appropriate error handling
  • Delegates to shared component with correct projectMeta construction
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (1)

1-29: LGTM! Consistent implementation following the established pattern.

This implementation is consistent with the settings page and correctly follows the bridge pattern for team/project scoped routing.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.tsx (1)

6-6: LGTM! Clean addition of projectMeta support.

The changes correctly add projectMeta prop support to enable team/project scoped routing. The implementation is minimal, well-typed, and follows the established pattern.

Also applies to: 14-14, 20-20, 49-49

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx (1)

6-10: Good call on awaiting props.params

This matches the quirky Next.js behaviour we learnt previously (params occasionally arrive as a Promise).
No action needed.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx (1)

4-8: Double-check whether params really needs to be awaited on this route

Unlike the team/... routes, this file hasn’t introduced a custom segment that triggers the params-as-Promise quirk.
Awaiting an object that’s already synchronous is harmless, but it does hide potential type mismatches and can confuse future maintainers.

Please verify with:

export default function Page({ params }: { params: { /* … */ } }) {

If it compiles, prefer the synchronous version; otherwise keep the await and add a short comment explaining the rationale.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/cross-chain/page.tsx (1)

1-29: LGTM! Clean implementation of the project-scoped contract page pattern.

The implementation correctly follows the established pattern:

  • Properly extracts and awaits route parameters
  • Fetches project data with appropriate error handling via notFound()
  • Delegates rendering to the shared component with well-structured projectMeta
  • Maintains type safety with ProjectContractPageParams

The long relative import path for SharedCrossChainPage is consistent with the established file structure, though it could benefit from path mapping in the future.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx (1)

53-54: Good prop propagation for project-scoped routing.

The addition of teamSlug and projectSlug props follows a clean pattern:

  • Props are consistently extracted from the fetched team/project objects
  • Proper threading through the component hierarchy to FactoryContracts
  • Maintains backward compatibility while enabling project-scoped URL construction

This aligns well with the broader refactor to support team/project context in contract-related pages.

Also applies to: 65-66, 105-106, 117-118, 151-152

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx (1)

1-19: Excellent refactor to shared component pattern.

The simplification effectively centralizes complex logic in SharedAccountsPage while maintaining the same functionality:

  • Proper delegation to the shared component with correct parameter mapping
  • projectMeta: undefined appropriately indicates this is a non-project-scoped route
  • Parameter rename from chain_id to chainIdOrSlug improves consistency across the codebase

The shared component handles all the previously embedded logic including contract fetching, account validation, and conditional rendering based on chain type and contract capabilities.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1)

1-19: Consistent implementation of the shared component pattern.

This refactor follows the same excellent pattern as the accounts page:

  • Clean delegation to SharedDirectListingsPage with proper parameter mapping
  • Correct use of projectMeta: undefined for non-project-scoped routes
  • Consistent parameter naming with chainIdOrSlug

The shared component encapsulates all the complex logic including account fetching, contract validation, marketplace capability checks, and conditional rendering that was previously embedded in this page.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/claim-conditions/page.tsx (1)

6-29: LGTM! Well-structured server component implementation.

The page follows a clean pattern of parameter resolution, data fetching, error handling, and delegation to a shared component. The async/await handling and 404 error responses are implemented correctly.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx (1)

25-38: LGTM! Clean implementation of project-scoped URL generation.

The conditional contractRootPath logic correctly builds team/project-prefixed URLs when projectMeta is available, enabling proper navigation within project contexts.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/page.tsx (1)

10-18: LGTM! Excellent refactoring that centralizes logic.

The simplified implementation that delegates contract data fetching and validation to SharedEventsPage is a good architectural decision. Setting projectMeta: undefined is correct for this non-project context.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx (1)

6-29: LGTM! Consistent implementation following established patterns.

The page correctly implements the pattern established across other contract pages: parameter resolution, project data fetching, error handling, and delegation to shared components. The async/await handling is proper per Next.js server component requirements.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/page.tsx (2)

3-9: Remove unnecessary Promise wrapper around params

params is synchronously injected by Next.js and is not a Promise.
Typing it as Promise<…> and awaiting it:

  • introduces an avoidable async render path,
  • forces the whole component to be async,
  • makes the call-site contract inaccurate (Next.js will pass an object, not a promise).

A small refactor simplifies the file and removes the superfluous await.

-export default async function Page(props: {
-  params: Promise<{
-    contractAddress: string;
-    chain_id: string;
-  }>;
-}) {
-  const params = await props.params;
+export default function Page(props: {
+  params: {
+    contractAddress: string;
+    chain_id: string;
+  };
+}) {
+  const { params } = props;

If you still need the function to be async for other reasons (e.g. headers, cookies) you can keep async while dropping the Promise type.
[ suggest_essential_refactor ]


14-16: Consider normalising the chain_id key

Internally you map chain_id → chainIdOrSlug.
If possible, expose the canonical name (chainIdOrSlug) at the route level to avoid this translation step and reduce chances of a typo drifting between files.
If changing the route segment is not feasible, at least add a comment here explaining the mismatch for future readers.
[ suggest_nitpick ]

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx (2)

3-9: Same params Promise issue as above

The NFT token page repeats the Promise pattern.
Please apply the same refactor as suggested for the overview page to keep the codebase consistent and accurate.
[ duplicate_comment ]


14-18: Guard against missing projectMeta to avoid prop churn

You explicitly pass projectMeta: undefined.
Because the property is already optional in the shared component, omitting it entirely keeps the call-site cleaner and prevents ESLint/TS from propagating “possibly undefined” checks downstream.

-        tokenId: params.tokenId,
-        projectMeta: undefined,
+        tokenId: params.tokenId,

[ suggest_nitpick ]

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx (4)

6-6: Brittle deep-relative import for ProjectMeta

The import path climbs six directories and reaches into a route-specific folder:

import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";

This is highly fragile:

  • a single folder rename will break every consumer,
  • it creates an accidental dependency on a page-layer file from a shared component, risking circular builds.

Move ProjectMeta to a central types (e.g. @/types/project) and reference it via a path alias to improve stability.

-import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/types/project";

[ suggest_essential_refactor ]


33-34: Prop should be optional

The prop is declared as projectMeta: ProjectMeta | undefined; but not marked optional (?).
Marking it optional improves DX and matches usage patterns.

-interface NFTCardsProps {
+interface NFTCardsProps {
   ...
-  projectMeta: ProjectMeta | undefined;
+  projectMeta?: ProjectMeta;
 }

[ suggest_nitpick ]


49-52: Avoid manual string concatenation for routes

Building URLs with template literals is error-prone and duplicates knowledge of routing rules.
Consider a helper:

import { buildContractPath } from "@/lib/paths";
...
const href = buildContractPath({
  projectMeta,
  chainId: token.chainId,
  contractAddress: token.contractAddress,
  slug: `nfts/${tokenId}`,
});

Centralising route logic prevents drift when path patterns evolve (e.g., moving from /team to /t).
[ suggest_optional_refactor ]


95-98: Missing leading slash when projectMeta is defined

contractRootPath already starts with a /.
When projectMeta is not defined, the final URL correctly starts with /.
When projectMeta is defined, the concatenation yields
/team/.../contract/<chain>/<address>/nfts/<id> — ✅
Just sanity-checked: there is no double slash, so nothing breaks here.
[ approve_code_changes ]

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/accounts/page.tsx (1)

1-29: LGTM! Clean implementation following established patterns.

This page component follows the established pattern for team/project-scoped contract pages:

  • Proper async/await usage with Next.js App Router
  • Appropriate error handling with notFound() for missing teams
  • Clean delegation to shared component logic
  • Correctly constructed projectMeta object matching the ProjectMeta type

The implementation is consistent with other similar pages in the codebase.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/LatestEvents.tsx (2)

31-43: LGTM! Clean conditional URL construction.

The implementation correctly:

  • Maintains backward compatibility with undefined projectMeta
  • Constructs project-scoped URLs when projectMeta is available
  • Uses the constructed path to build the events link

This follows the established pattern for project-aware routing.


25-25:

✅ Verification successful

Verify import path consistency.

The import uses a relative path with many directory traversals. Consider whether this could be simplified with a path alias or if it matches the pattern used in other similar imports across the codebase.


🏁 Script executed:

#!/bin/bash
# Check if there's a consistent pattern for ProjectMeta imports across the codebase
rg -A 2 -B 2 "import.*ProjectMeta" --type tsx --type ts

Length of output: 85


To verify consistency of ProjectMeta imports and check for any path aliases:


🏁 Script executed:

#!/bin/bash
# 1. Find all imports of ProjectMeta in .ts/.tsx files
rg "import.*ProjectMeta" --glob "*.ts" --glob "*.tsx" -n

Length of output: 14250


🏁 Script executed:

#!/bin/bash
# 2. Inspect tsconfig.json for configured path aliases
grep -R '"paths"' -n tsconfig.json && sed -n '/"paths"\s*:/,/\]/p' tsconfig.json

Length of output: 83


Import path consistency confirmed

All ProjectMeta imports in the dashboard use the same deep-relative path pattern and there’s no path alias configuration in the repo (no tsconfig.json defining paths was found). This matches other components—no changes needed.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.tsx (3)

24-59: LGTM! Comprehensive URL construction with proper dependencies.

The implementation correctly:

  • Adds projectMeta to component props interface
  • Constructs conditional URL paths for all navigation links
  • Maintains backward compatibility when projectMeta is undefined
  • Uses the constructed paths consistently throughout the component

The approach is thorough and follows the established pattern.


347-367: Excellent dependency management in useMemo.

Good practice including all the href variables in the useMemo dependency array. This ensures the steps are recalculated when the URL paths change based on project context.


15-15:

✅ Verification successful

Verify import path consistency.

Similar to the previous file, this uses a deeply nested relative import path. Ensure this pattern is consistent across the codebase.


🏁 Script executed:

#!/bin/bash
# Check for consistent ProjectMeta import patterns
rg "import.*ProjectMeta.*from.*team.*project_slug.*types" --type tsx --type ts

Length of output: 108


🏁 Script executed:

#!/bin/bash
# Search for all ProjectMeta imports across TS and TSX files without type filters
rg "import.*ProjectMeta.*from" -g "*.ts" -g "*.tsx"

Length of output: 14117


Import path consistency verified.

The ProjectMeta import uses the appropriate number of ../ across all files relative to their directory depth, matching the pattern in other components. No changes needed.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1)

1-54: LGTM! Well-structured shared component with excellent async patterns.

This implementation demonstrates several best practices:

  • Efficient data fetching: Uses Promise.all to concurrently fetch contract info and auth token
  • Proper error handling: Returns notFound() when contract info is missing
  • Clean separation of concerns: Delegates to appropriate components based on chain type
  • Type safety: Properly typed parameters including optional projectMeta
  • Consistent patterns: Follows the established pattern for shared contract page components

The component successfully centralizes the async logic while maintaining flexibility for different rendering contexts.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (3)

6-6: LGTM: Proper type import for ProjectMeta

The import correctly references the ProjectMeta type from the team/project types file.


10-11: LGTM: Interface updated to include projectMeta

The addition of the optional projectMeta prop with correct typing aligns with the broader refactor pattern across the dashboard.


22-30: LGTM: Conditional URL construction logic is correct

The conditional logic properly handles both scenarios:

  • Without projectMeta: uses legacy URL format /{chainId}/{contractAddress}
  • With projectMeta: uses project-scoped format /team/{teamSlug}/{projectSlug}/contract/{chainId}/{contractAddress}

The destructuring of teamSlug and projectSlug is safe since the conditional check ensures projectMeta is defined.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx (2)

1-1: LGTM: Proper delegation to shared component

The import of SharedPermissionsPage follows the established pattern for this refactor.


11-17: LGTM: Clean parameter mapping and delegation

The page component is correctly simplified to delegate all logic to SharedPermissionsPage. Key improvements:

  1. Parameter mapping: chain_idchainIdOrSlug aligns with the shared component's interface
  2. Explicit projectMeta: Setting to undefined clearly indicates this is a non-project route
  3. Logic delegation: Complex contract fetching, validation, and conditional rendering is now handled by the shared component

This pattern improves maintainability and consistency across the codebase.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx (5)

31-31: LGTM: Correct type import

The import properly references the ProjectMeta type from the team/project types file.


57-57: LGTM: Interface updated with projectMeta

The addition of the optional projectMeta prop maintains backward compatibility while enabling project-scoped functionality.


68-68: LGTM: Component parameter updated

The component correctly accepts the new projectMeta parameter for use in path construction.


74-76: LGTM: Conditional path construction

The contractRootPath logic correctly handles both scenarios:

  • With projectMeta: constructs /team/{teamSlug}/{projectSlug}/contract prefix
  • Without projectMeta: uses empty string (maintains existing behavior)

This pattern aligns with the broader refactor across the dashboard.


139-144: LGTM: Breadcrumb navigation updated consistently

The breadcrumb link correctly uses the contractRootPath for both the href and the router.push call, ensuring consistent navigation behavior in project-scoped and legacy contexts.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx (2)

1-1: LGTM: Consistent delegation pattern

The import of SharedContractAccountPage follows the established refactor pattern across the dashboard.


11-17: LGTM: Effective simplification with proper delegation

The page component successfully delegates all complex logic to SharedContractAccountPage. This refactor provides several benefits:

  1. Consistency: Follows the same pattern as other contract pages (permissions, direct-listings, etc.)
  2. Maintainability: Complex logic is centralized in the shared component
  3. Clear intent: Explicit projectMeta: undefined indicates non-project context
  4. Parameter mapping: chain_idchainIdOrSlug aligns with shared component interface

The previous complex logic for contract info fetching, localhost handling, and conditional rendering is now properly encapsulated in the shared component.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx (2)

17-25: Good use of parallel data fetching.

The parallel fetching of contract info and account data using Promise.all is an efficient approach that reduces the overall loading time.


45-51: Proper validation and redirect handling.

The ERC standard validation and redirect to the contract landing page for unsupported contracts follows good defensive programming practices.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageSidebarLinks.ts (1)

15-17: Clean implementation of project-scoped URL construction.

The conditional layoutPrefix construction properly handles both project-scoped and legacy URL patterns, maintaining backward compatibility while enabling the new functionality.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx (1)

11-17: Excellent refactoring to shared component pattern.

The simplification of this page component by delegating to SharedEnglishAuctionsPage reduces code duplication and centralizes the contract page logic. The parameter mapping and explicit projectMeta: undefined are appropriate for this non-project-scoped route.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx (2)

53-55: Consistent implementation of project-scoped URL construction.

The contractRootPath construction follows the same pattern established in the sidebar links utility, ensuring consistent URL handling across the dashboard.


67-67: Proper integration of project-scoped path in code snippets link.

The code snippets button correctly uses the constructed contractRootPath to maintain URL consistency within project contexts.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx (4)

61-61: LGTM: Correct import of ProjectMeta type.

The import path correctly references the ProjectMeta type definition from the team/project contract types.


95-95: LGTM: Proper prop interface integration.

The projectMeta prop is correctly added as optional to both the function signature and props interface, maintaining backward compatibility.

Also applies to: 105-105


246-250: LGTM: Correct conditional URL construction for network links.

The URL construction properly handles both project-scoped and non-project-scoped routing by conditionally prefixing with team and project slugs when projectMeta is available.


417-421: LGTM: Consistent URL construction for deploy status modal.

The view contract link construction follows the same conditional pattern as the network links, ensuring consistent navigation behavior throughout the component.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx (3)

2-2: LGTM: Correct import of ProjectMeta type.

The import correctly references the ProjectMeta type definition for use in the component props.


24-24: LGTM: Proper prop interface and component integration.

The projectMeta prop is correctly added as optional to the interface and component props, maintaining consistency with other components in the refactor.

Also applies to: 41-41


53-53: LGTM: Consistent prop propagation to child components.

All relevant child components (ContractChecklist, ContractAnalyticsOverviewCard, MarketplaceDetails, NFTDetails, LatestEvents, PermissionsTable, and BuildYourApp) properly receive the projectMeta prop, enabling project-scoped behavior throughout the component tree.

Also applies to: 62-62, 69-69, 83-83, 93-93, 101-101, 109-109

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx (2)

44-44: LGTM: Correct import of ProjectMeta type.

The import correctly references the ProjectMeta type definition with proper relative path resolution.


50-50: LGTM: Proper prop interface integration.

The projectMeta prop is correctly added as optional to both the interface and component props.

Also applies to: 56-56

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx (5)

1-7: LGTM: Proper imports and dependencies.

All necessary imports are correctly included, including the ProjectMeta type, utility functions, and components needed for the server component.


8-14: LGTM: Well-structured component interface.

The props interface is properly typed with clear parameter structure including the optional projectMeta for team/project context.


16-24: LGTM: Proper data fetching and error handling.

The component correctly calls getContractPageParamsInfo with the teamId from projectMeta and properly handles the 404 case when no contract information is found.


29-36: LGTM: Appropriate conditional rendering for localhost chains.

The component correctly handles localhost chains by rendering the client-side component, which is necessary for chains that may not have server-side contract resolution capabilities.


38-46: LGTM: Robust ABI resolution with error handling.

The ABI resolution includes proper error handling with .catch(() => undefined), ensuring the component doesn't crash if ABI resolution fails, and gracefully passes undefined to the server component.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx (1)

9-53: Well-structured shared component with good performance patterns.

This component effectively centralizes the explorer page logic with several good practices:

  • Parallel data fetching using Promise.all for optimal performance
  • Graceful error handling for ABI resolution failures
  • Clean conditional rendering based on chain type
  • Proper 404 handling for missing contract information

The architecture promotes code reuse while maintaining type safety with the optional ProjectMeta parameter.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (1)

10-56: Excellent implementation with robust fee configuration handling.

The component demonstrates several best practices:

  • Efficient parallel data fetching with Promise.all
  • Robust platform fee checking with proper error handling (lines 42-46)
  • Correct case-insensitive address comparison for fee recipient validation
  • Consistent error handling pattern with notFound() for missing contract info

The fee configuration logic gracefully handles contracts that don't support platform fees by catching exceptions and defaulting to true.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx (1)

9-54: Consistent implementation following established patterns.

This component maintains the architectural consistency seen across other shared pages:

  • Efficient parallel data fetching for account and contract information
  • Proper feature validation (direct listing support) before rendering
  • Correct error handling with notFound() for unsupported features
  • Clean separation between localhost and production chain handling

The projectMeta propagation to client components enables proper project-scoped routing.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx (1)

29-53: Clean feature validation and rendering logic.

The remaining implementation is excellent:

  • Proper feature support validation for English auctions
  • Consistent error handling with notFound() for unsupported features
  • Correct prop propagation including projectMeta for project-scoped routing
  • Clean separation between client and server rendering paths
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx (3)

1-15: LGTM! Clean component structure and imports.

The component follows the consistent pattern established for shared contract components, with proper imports and TypeScript typing.


16-28: Correct contract info fetching and error handling.

The component properly fetches contract information using the team context and handles the 404 case appropriately.


29-37: Localhost rendering implemented correctly.

The client component receives all necessary props including projectMeta for proper navigation handling.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx (1)

1-27: Well-structured shared component following established pattern.

The component correctly implements the contract info fetching, error handling, and conditional rendering logic consistent with other shared contract components.

Also applies to: 30-45

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx (2)

29-34: Excellent use of concurrent fetching for performance.

The Promise.all implementation with conditional metadata fetching for non-localhost chains is a good performance optimization.


50-56: Good consistency in projectMeta prop passing.

Unlike some other shared components, this correctly passes projectMeta to both client and server components for consistent behavior.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx (1)

1-59: Excellent implementation following best practices.

This shared component demonstrates the most consistent implementation of the established pattern:

  • Proper variable naming (account instead of variations)
  • Consistent projectMeta passing to both client and server components
  • Includes chainMetadata where needed
  • Clean error handling and conditional rendering

This serves as a good reference for the other shared components.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx (1)

1-50: LGTM! Well-structured shared component with proper error handling.

This shared component follows an excellent pattern by centralizing contract token page logic with proper error handling and conditional rendering. The implementation correctly:

  • Fetches contract information with appropriate error handling
  • Separates localhost and remote chain rendering paths
  • Uses ERC20 feature detection via function selectors
  • Passes the correct props to child components
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx (1)

37-44: Good feature validation with appropriate error handling.

The component properly validates that the contract supports account permissions before rendering, and returns a 404 if not supported. This provides a better user experience than showing an error page.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/page.tsx (1)

11-17: Clean refactor that delegates logic to shared component.

This simplification effectively moves complex cross-chain logic into the shared component while maintaining the same functionality. Setting projectMeta: undefined is appropriate for non-project-scoped routes.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx (1)

42-50: Good feature validation with proper redirect handling.

The component correctly validates modular core support and redirects to the contract landing page when not supported, properly passing through the project metadata for consistent navigation.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx (2)

28-30: Missing account null-check before render

getValidAccount might return undefined, yet account is passed to
<TeamHeaderLoggedIn> which expects a valid object.
Add a guard to avoid runtime crashes:

if (!account) {
  redirect("/login");
}

16-22: ⚠️ Potential issue

params should not be declared as a Promise

Next.js injects params synchronously (Record<string,string>).
Typing it as Promise<...> forces you to await something that is not a thenable,
silently widening the type and hiding real compiler errors.

-export default async function ContractLayout(props: {
-  children: React.ReactNode;
-  params: Promise<ProjectContractPageParams>;
-}) {
-  const params = await props.params;
+export default async function ContractLayout(props: {
+  children: React.ReactNode;
+  params: ProjectContractPageParams;
+}) {
+  const params = props.params;
⛔ Skipped due to learnings
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (1)

131-159: 🛠️ Refactor suggestion

Parallelise inner getProjects calls to avoid N×M latency

Promise.all already gathers the outer promises concurrently, but each async mapper awaits getProjects inside the callback, forcing the getProjects calls to execute sequentially (one per team).
You can shave seconds off the dashboard load time for users that belong to many teams by starting all project-fetch requests at once:

-    const teamsAndProjects: MinimalTeamsAndProjects = await Promise.all(
-      teams.map(async (team) => ({
-        team: {
-          id: team.id,
-          name: team.name,
-          slug: team.slug,
-          image: team.image,
-        },
-        projects: (await getProjects(team.slug)).map((x) => ({
-          id: x.id,
-          name: x.name,
-          image: x.image,
-        })),
-      })),
-    );
+    const teamsAndProjects: MinimalTeamsAndProjects = await Promise.all(
+      teams.map(async (team) => {
+        const projects = await getProjects(team.slug); // kick off in parallel
+        return {
+          team: {
+            id: team.id,
+            name: team.name,
+            slug: team.slug,
+            image: team.image,
+          },
+          projects: projects.map((p) => ({
+            id: p.id,
+            name: p.name,
+            image: p.image,
+          })),
+        };
+      }),
+    );

(The key change is removing the immediate await inside map.)
For large organisations this reduces total wait time to the slowest single request instead of the sum of all requests.

Likely an incorrect or invalid review comment.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (1)

28-34: Confirm props signature aligns with Next.js routing

projectMeta is injected into params, but params normally only contains
path segments provided by the framework.
Ensure every page that calls <SharedCrossChainPage> manually passes
projectMeta inside the params object; otherwise this will always be undefined,
breaking team/project scoping.

If this was meant to be a separate prop, consider:

export async function SharedCrossChainPage({
  params,
  projectMeta,
}: {
  params: { contractAddress: string; chainIdOrSlug: string };
  projectMeta?: ProjectMeta;
}) {  }

Copy link

changeset-bot bot commented May 24, 2025

⚠️ No Changeset found

Latest commit: 1247502

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

@vercel vercel bot temporarily deployed to Preview – wallet-ui May 24, 2025 10:19 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 24, 2025 10:19 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 24, 2025 10:19 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 24, 2025 10:19 Inactive
@MananTank MananTank force-pushed the 05-24-add_contract_layout_in_team_project branch from fbfe157 to abf343e Compare May 24, 2025 10:23
@vercel vercel bot temporarily deployed to Preview – login May 24, 2025 10:23 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 24, 2025 10:23 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 24, 2025 10:23 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 24, 2025 10:23 Inactive
@MananTank MananTank force-pushed the 05-24-add_contract_layout_in_team_project branch from abf343e to 139648c Compare May 24, 2025 11:28
@MananTank MananTank force-pushed the 05-24-add_contract_layout_in_team_project branch from dc995cc to 3f5b1f2 Compare May 26, 2025 14:14
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 26, 2025 14:14 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 26, 2025 14:14 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 26, 2025 14:14 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 26, 2025 14:14 Inactive
@MananTank MananTank force-pushed the 05-24-add_contract_layout_in_team_project branch from 3f5b1f2 to 5f65eea Compare May 26, 2025 14:17
@vercel vercel bot temporarily deployed to Preview – login May 26, 2025 14:17 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 26, 2025 14:17 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 26, 2025 14:17 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 26, 2025 14:17 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: 14

🔭 Outside diff range comments (3)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx (1)

89-105: ⚠️ Potential issue

“All” option never triggers navigation – broaden the guard

When the user switches back to “All”, eventTypes.includes("all") is false, therefore the router does not update the URL and the state stays stale.

- if (eventTypes.includes(val)) {
+ if (val === "all" || eventTypes.includes(val)) {

This restores the old behaviour and keeps the UI/URL in sync.

@@
- if (eventTypes.includes(val)) {
+ if (val === "all" || eventTypes.includes(val)) {
   const path = buildContractPagePath({
     projectMeta,
     chainIdOrSlug: chainSlug.toString(),
     contractAddress: contract.address,
     subpath:
       e.target.value === "all"
         ? "/events"
         : `/events?event=${val}`,
   });
   router.push(path);
   setSelectedEvent(val);
 }
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx (1)

22-27: 🛠️ Refactor suggestion

params is not a Promise – drop the await and fix the type

Next.js supplies params synchronously. Typing it as Promise<…> and awaiting works at runtime (since await on a non-promise is a no-op) but misleads type-checking and future maintainers.

-export default async function Page(props: {
-  params: Promise<{ team_slug: string; project_slug: string }>;
-}) {
-  const params = await props.params;
+export default async function Page(props: {
+  params: { team_slug: string; project_slug: string };
+}) {
+  const { params } = props;

This also eliminates an unnecessary micro-task hop.
After applying, no other lines need changes because params is still an in-scope constant.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx (1)

15-18: ⚠️ Potential issue

params should not be typed as Promise

next/router passes params synchronously. Declaring it as Promise<…> forces an unnecessary await, hides type-checking errors, and allows accidental misuse elsewhere.

-export default async function Page(props: {
-  params: Promise<{ team_slug: string; project_slug: string }>;
-}) {
-  const params = await props.params;
+export default async function Page(props: {
+  params: { team_slug: string; project_slug: string };
+}) {
+  const { params } = props;

After the change, drop await wherever props.params was previously awaited.

♻️ Duplicate comments (23)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/ContractSplitPage.client.tsx (1)

4-4: Deep relative import path issue (duplicate concern)

This is a duplicate of the previously flagged maintainability concern about deep relative import paths for the ProjectMeta type.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx (1)

4-4: Deep relative import path issue (duplicate concern)

This is a duplicate of the previously flagged maintainability concern about deep relative import paths for the ProjectMeta type.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx (1)

5-5: Even deeper relative import path creates maintainability risks

This file uses an even deeper relative import path (7 levels up) for the ProjectMeta type, which is worse than the previously flagged 6-level imports. This creates significant maintainability overhead and tight coupling.

Consider centralizing this type import:

-import type { ProjectMeta } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/types/project-meta";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.client.tsx (1)

5-5: Deep relative import path issue (duplicate concern)

This is a duplicate of the previously flagged maintainability concern about deep relative import paths for the ProjectMeta type.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx (1)

136-141: Same remark as above – centralise base path creation

Repeating the call here invites drift. See previous comment.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/page.tsx (1)

5-7: Align with Next JS page prop conventions

Same as in modules/page.tsx, props.params should be a plain object, not a promise. This type misuse leaks into every consumer of PublicContractPageParams.

[same reasoning → please fix across the board]

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx (1)

6-8: Incorrect param typing (promise vs value) repeats here

Follow the fix recommended in modules/page.tsx to keep consistency with Next JS expectations.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/page.tsx (1)

4-8: Same signature mismatch as in Explorer page

See the comment in explorer/page.tsx: the params prop should not be typed as Promise<>. Apply the same fix here for consistency and to remove the superfluous await.
(Leaving a dangling await will compile, but add an unnecessary micro-tick to every request.)

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx (1)

5-9: Drop the Promise wrapper for params here as well

Replicate the fix suggested for the Explorer & Events pages to keep the typing consistent and avoid the unnecessary await.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx (2)

5-8: Same Promise misuse for params as in settings page

The issue described in the previous file recurs here. Adopt the same correction pattern to keep typings accurate and avoid redundant awaits.


10-14: Drop unnecessary projectMeta={undefined} prop

See previous justification; omit the prop for cleaner JSX.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx (2)

5-8: Incorrect asynchronous typing of params

Replicates the Promise-typing problem outlined earlier; adjust the signature and await usage accordingly.


10-14: Remove explicit undefined for optional projectMeta

Consistent with prior pages, drop the prop for brevity.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/accounts/page.tsx (1)

25-25: Consider making the login status dynamic (same issue as claim-conditions page).

Similar to the claim-conditions page, the isLoggedIn prop is hardcoded to true. Consider fetching the actual authentication state for consistency.

This is the same issue identified in the claim-conditions page. Consider applying a similar fix to make the authentication status dynamic rather than hardcoded.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx (1)

47-50: Fix projectMeta inconsistency between client and server components.

The server component ContractSplitPage doesn't receive the projectMeta prop while the client component does. This creates inconsistent behavior between localhost and non-localhost environments.

Apply this diff to maintain consistency:

  return (
    <ContractSplitPage
      contract={clientContract}
      isLoggedIn={props.isLoggedIn}
+     projectMeta={props.projectMeta}
    />
  );
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx (1)

48-52: 🛠️ Refactor suggestion

Consider passing projectMeta to server component for consistency.

Similar to other shared components, the server component doesn't receive projectMeta while the client version does, which could lead to inconsistent navigation behavior.

Consider adding projectMeta to maintain consistency:

  return (
    <ContractEditModulesPage
      contract={clientContract}
      isLoggedIn={props.isLoggedIn}
+     projectMeta={props.projectMeta}
    />
  );
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx (1)

46-51: Server component missing projectMeta prop for consistency.

The server component ContractProposalsPage doesn't receive the projectMeta prop, while the client version does. This could lead to inconsistent navigation behavior between localhost and production environments.

Consider updating to include projectMeta:

  return (
    <ContractProposalsPage
      contract={clientContract}
      isLoggedIn={props.isLoggedIn}
+     projectMeta={props.projectMeta}
    />
  );
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (1)

37-56: Guard against supportedERCs being undefined

The previous review already highlighted this; the crash pathway is still present:

isERC20={supportedERCs.isERC20}

getContractPageMetadata can return supportedERCs === undefined on failure -> runtime TypeError.
Add a nullish check or default fallback before property access.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx (3)

4-4: Duplicate issue: Avoid invoking code from .client modules inside a Server Component

This import violates React Server Component rules as previously identified. The getClientThirdwebClient function is imported from a .client module which should not be used directly in server components.


40-50: Duplicate issue: N + 1 fetch pattern – fetch only the current team's projects

This code fetches projects for every team but only uses projects from the matching team, creating unnecessary database load and latency as previously identified.


56-60: ⚠️ Potential issue

Critical RSC violation will cause build failure

Using getClientThirdwebClient from a .client module inside this server component will cause a build-time error. This violates React Server Component architecture.

Move the client creation to a server-safe location or wrap this in a client component:

- import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
+ import { getClientThirdwebClient } from "@/constants/thirdweb-client.server";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1)

32-41: Duplicate issue: Over-restrictive token-ID validation blocks legitimate NFTs

The isOnlyNumbers function only accepts decimal-numeric IDs, which will block valid hex or string token IDs used by many ERC-721/ERC-1155 contracts as previously identified.

Also applies to: 78-80

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (1)

227-232: Duplicate issue: Off-by-one bug causes modules list to be dropped when it is the first arg

The findIndex returns 0 when the matching parameter is first, but the ternary treats 0 as falsy, incorrectly setting modules to undefined as previously identified.

🧹 Nitpick comments (48)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx (1)

5-5: Consider optimizing the import path.

The deep relative import path with many "../" segments could be brittle and hard to maintain if the file structure changes.

Consider using a path alias or barrel export to simplify the import:

-import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/types/contract"; // or similar alias
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/ContractProposalsPage.client.tsx (1)

4-4: Consider optimizing the import path.

Same issue as in other files - the deep relative import path could be brittle. Consider using a path alias for better maintainability.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx (1)

4-4: Consider optimizing the import path.

The deep relative import path follows the same pattern as other files in this PR. Consider establishing a consistent import alias strategy across the project for better maintainability.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/PermissionsTable.tsx (1)

31-37: Consider memoising permissionsHref to avoid redundant recomputations

buildContractPagePath is executed on every render even though its inputs rarely change. Wrapping it in useMemo prevents unnecessary string building and keeps the dependency graph explicit.

-  const permissionsHref = buildContractPagePath({
-    projectMeta: props.projectMeta,
-    chainIdOrSlug: props.chainSlug,
-    contractAddress: props.contract.address,
-    subpath: "/permissions",
-  });
+  const permissionsHref = useMemo(
+    () =>
+      buildContractPagePath({
+        projectMeta: props.projectMeta,
+        chainIdOrSlug: props.chainSlug,
+        contractAddress: props.contract.address,
+        subpath: "/permissions",
+      }),
+    [props.projectMeta, props.chainSlug, props.contract.address],
+  );

(The file already imports useMemo, so no additional imports are needed.)
Impact is minor, hence purely a micro-optimisation.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx (1)

55-61: Lazy-compute codePagePath to avoid unnecessary work

codePagePath is computed even in branches where it will never be used (e.g., when the component immediately returns null). Wrapping the calculation in useMemo defers the work until needed and makes dependencies explicit.

-  const codePagePath = buildContractPagePath({
-    projectMeta,
-    chainIdOrSlug: contractInfo.chainSlug,
-    contractAddress: contractAddress,
-    subpath: "/code",
-  });
+  const codePagePath = useMemo(
+    () =>
+      buildContractPagePath({
+        projectMeta,
+        chainIdOrSlug: contractInfo.chainSlug,
+        contractAddress: contractAddress,
+        subpath: "/code",
+      }),
+    [projectMeta, contractInfo.chainSlug, contractAddress],
+  );

Remember to import useMemo at the top of the file:

-import { useState } from "react";
+import { useState, useMemo } from "react";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx (1)

36-38: Extremely long relative import path – consider an alias to improve maintainability

../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types is very fragile.
A single folder move will break many files that copy-paste this path. Adding a TS path alias (e.g. @contract/types) keeps the import stable and the codebase readable.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx (3)

55-61: Duplicated path-building logic – extract to a helper

DirectListingCards and EnglishAuctionCards build their section root with an identical buildContractPagePath invocation.
Creating const contractBase = buildContractPagePath({ … }) once in the parent (or a custom hook) avoids duplication and guarantees both sections stay in sync when the path rules evolve.


307-318: Trailing slash ambiguity in derived URLs

const contractLayout = buildContractPagePath({ … }) is later concatenated with "/direct-listings" and "/english-auctions".
If the util ever returns a path with a trailing slash, the final URL will contain a double slash. Safeguard by using join semantics or contractLayout.replace(/\/$/, "").


312-312: Mutating prop argument listings violates React best practices

listings = isPending ? … : listings.slice(0,3) reassigns the prop variable.
Prefer a new local:

const visibleListings = isPending
  ? Array.from({ length: 3 }).map((_, idx) => dummyMetadata(idx))
  : listings.slice(0, 3);

This avoids accidental side-effects if the array reference is used elsewhere.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/ContractDirectListingsPage.client.tsx (3)

4-5: Alias or barrel export recommended for shared ProjectMeta type

The deeply nested relative path is hard to maintain. Exposing ProjectMeta from a central barrel (e.g. @types/project) keeps import statements short and robust.


13-14: Props interface should be declared once for clarity

Inline object types scale poorly as the prop list grows. Declare an interface:

interface ContractDirectListingsPageClientProps {
  contract: ThirdwebContract;
  isLoggedIn: boolean;
  projectMeta?: ProjectMeta;
}

and use it in both the function and elsewhere to stay DRY.


27-31: Forwarding projectMeta is good – consider also forwarding isLoggedIn for consistency

RedirectToContractOverview might eventually need login state to decide between public/project scopes. Passing it now future-proofs the call.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx (1)

4-4: Prefer path alias over deep relative import

The 6-level relative path is fragile and hurts readability. Consider introducing a TS/webpack alias such as @/app/team/.../types (or re-export ProjectMeta from a central barrel) to shorten the import and make future moves/renames safer.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/BuildYourApp.tsx (1)

4-6: Same alias remark applies

Deep relative imports for both ProjectMeta and buildContractPagePath could be replaced with an alias to improve maintainability.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/page.tsx (1)

14-16: Double-check projectMeta={undefined}

If the shared page expects ProjectMeta | undefined, this is fine. Otherwise, pass projectMeta={null} or omit the prop to avoid unnecessary explicit undefined.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx (2)

2-3: Avoid importing types and values from different directory levels in the same block

PublicContractPageParams lives next to types.ts, whereas SharedModulesPage is under the local modules sub-folder. Importing them in a single group blurs the distinction between external/public types and local implementation files.

-import type { PublicContractPageParams } from "../types";
-import { SharedModulesPage } from "./shared-modules-page";
+import type { PublicContractPageParams } from "../types"; // public contract route types
+
+// local module implementation
+import { SharedModulesPage } from "./shared-modules-page";

[nitpick]


10-15: Pass optional props as truly optional

If projectMeta is declared optional in SharedModulesPageProps, sending undefined is redundant; omitting the prop tightens the contract and avoids | undefined noise through the component tree.

-    <SharedModulesPage
-      contractAddress={params.contractAddress}
-      chainIdOrSlug={params.chain_id}
-      projectMeta={undefined}
-      isLoggedIn={!!account}
-    />
+    <SharedModulesPage
+      contractAddress={params.contractAddress}
+      chainIdOrSlug={params.chain_id}
+      isLoggedIn={!!account}
+    />
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/page.tsx (1)

9-13: Omit undefined optional prop

If projectMeta is optional in SharedContractSourcesPage, leave it out for clarity.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx (1)

11-15: Pass only the necessary props

Same redundant projectMeta={undefined} issue as above; remove it to simplify the API surface.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (1)

1-5: Consider simplifying complex import paths.

The deeply nested relative import paths (e.g., ../../../../../../../) are fragile and hard to maintain. Consider using absolute imports or path aliases for better maintainability.

Example using path aliases:

-import { SharedContractAccountPage } from "../../../../../../../(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page";
-import { getProject } from "../../../../../../../../../@/api/projects";
+import { SharedContractAccountPage } from "@/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page";
+import { getProject } from "@/api/projects";
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1)

1-4: Consider simplifying complex import paths.

Similar to the other files, the deeply nested relative import paths could be simplified using absolute imports or path aliases for better maintainability.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx (1)

12-14: Normalise naming – prefer one param key (chainIdOrSlug) throughout

Here we transform params.chain_idchainIdOrSlug={…}.
Mixing snake_case and camelCase in the same statement increases the mental load and is error-prone.

Consider renaming the dynamic segment in the route folder to [chainIdOrSlug] (matching the project-scoped routes) or introduce a small mapper:

const chainIdOrSlug = params.chain_id;

before passing it further.
Consistency here will prevent subtle typos when copying code between routes.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/page.tsx (1)

9-14: Prop naming / consistency nit

Same snake ↔ camel naming issue (params.chain_idchainIdOrSlug).
Recommend the same normalisation strategy as above.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/events/page.tsx (1)

20-24: Leverage existing slug instead of re-deriving it

params.project_slug is already validated by the router and matches the requested URL.
Passing project.slug (fetched value) back into projectMeta means a misconfigured API could silently diverge from the URL the user is on.

-  projectMeta={{
-    projectSlug: project.slug,
+  projectMeta={{
+    projectSlug: params.project_slug,

Keeps the UI fully driven by the route and avoids accidental inconsistencies.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx (1)

10-13: Naming consistency again (chain_id vs chainIdOrSlug)

Unify the parameter naming or create an alias variable before passing it to SharedCodePage.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx (1)

28-33: Excellent refactoring to use centralized URL building.

The change from hardcoded URL construction to using the buildContractPagePath utility is a great improvement. This centralizes URL logic and ensures consistency across the application.

This pattern should be applied consistently across all contract pages for maintainability.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx (1)

6-14: Consistent pattern with modules page.

The parameter handling and project fetching logic is identical to the modules page, which is good for consistency.

Consider extracting the common project fetching and validation logic into a shared utility function to reduce duplication:

// utils/project-page-wrapper.ts
export async function getProjectFromParams(params: ProjectContractPageParams) {
  const project = await getProject(params.team_slug, params.project_slug);
  if (!project) {
    notFound();
  }
  return project;
}

This could be used in both modules and explorer pages.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx (1)

11-14: Avoid explicit undefined for optional props

Passing projectMeta={undefined} clutters the JSX and provides no extra information. Omit the prop entirely:

-<SharedContractSettingsPage
-  contractAddress={params.contractAddress}
-  chainIdOrSlug={params.chain_id}
-  projectMeta={undefined}
-  isLoggedIn={!!account}
-/>

+<SharedContractSettingsPage
+  contractAddress={params.contractAddress}
+  chainIdOrSlug={params.chain_id}
+  isLoggedIn={!!account}
/>
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/claim-conditions/page.tsx (1)

25-25: Consider making the login status dynamic rather than hardcoded.

The isLoggedIn prop is hardcoded to true, which may not reflect the actual authentication state. Consider fetching the account status similar to how it's done in the public contract pages.

Apply this diff to make the login status dynamic:

+import { getRawAccount } from "../../../../../../../../account/settings/getAccount";

 export default async function Page(props: {
   params: Promise<ProjectContractPageParams>;
 }) {
-  const params = await props.params;
-  const project = await getProject(params.team_slug, params.project_slug);
+  const [params, account] = await Promise.all([
+    props.params,
+    getRawAccount()
+  ]);
+  const project = await getProject(params.team_slug, params.project_slug);

   if (!project) {
     notFound();
   }

   return (
     <SharedClaimConditionsPage
       contractAddress={params.contractAddress}
       chainIdOrSlug={params.chainIdOrSlug}
       projectMeta={{
         projectSlug: project.slug,
         teamId: project.teamId,
         teamSlug: params.team_slug,
       }}
-      isLoggedIn={true}
+      isLoggedIn={!!account}
     />
   );
 }
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx (1)

11-16: projectMeta={undefined} is redundant

projectMeta is optional in SharedContractProposalsPage, so passing undefined adds noise without value. Dropping it improves readability:

-    <SharedContractProposalsPage
-      contractAddress={params.contractAddress}
-      chainIdOrSlug={params.chain_id}
-      projectMeta={undefined}
-      isLoggedIn={!!account}
-    />
+    <SharedContractProposalsPage
+      contractAddress={params.contractAddress}
+      chainIdOrSlug={params.chain_id}
+      isLoggedIn={!!account}
+    />
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx (1)

10-16: Drop explicit undefined for projectMeta – idem to proposals page.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageSidebarLinks.ts (2)

2-4: Import path leaks feature-folder knowledge

ProjectMeta is imported from a deeply nested route path:

import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";

Coupling a utility to the route hierarchy hurts re-usability. Prefer re-exporting ProjectMeta from a central domain module (e.g. contracts/types) and import from there.


14-21: Variable naming drift (chainSlug vs chainIdOrSlug)

buildContractPagePath expects chainIdOrSlug, but the wrapper still uses chainSlug. Mixing terms makes the API harder to follow.

-  chainSlug: string;
+  chainIdOrSlug: string;
...
-    chainIdOrSlug: data.chainSlug,
+    chainIdOrSlug: data.chainIdOrSlug,

Aligning the names avoids accidental misuse.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (2)

6-7: Prefer root-alias import over brittle deep relative path

The 5-level ../../../../../… path is fragile – a single folder rename or move will silently break the import.
Using a root alias (e.g. @/app/(app)/team/...) or placing common types in a shared package keeps the path stable and improves readability.

-import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";

18-31: Effect dependency could be narrowed to avoid unnecessary executions

useEffect depends on the full props object.
Parents often pass a new object on every render, which will re-trigger the effect (it’s guarded by redirected.current, but the hook still wakes up).
Depending only on the handful of primitives used keeps React DevTools noise down and avoids redundant work:

-}, [router, props]);
+}, [
+  router,
+  props.contract.address,
+  props.contract.chain.id,
+  props.projectMeta?.teamId,   // if used inside buildContractPagePath
+]);
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1)

1-4: Replace deep relative import with alias for maintainability

Same concern as earlier: the 5-level climb is brittle. Prefer an alias or expose ProjectMeta from a central package.

-import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/contract-page-path.ts (1)

1-1: Prefer path alias over deep relative import

A 6-level relative path is fragile and becomes painful to maintain when files are moved. The rest of the dashboard codebase already uses the @/… alias – consider adding one for apps/dashboard/src/app (e.g. @dashboard/…) and importing

import type { ProjectMeta } from "@dashboard/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";

This keeps imports readable and avoids breakage on refactors.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx (1)

11-14: Consider passing real projectMeta when available

projectMeta={undefined} works for the public dashboard, but if this page ever lives under a team/project route, links generated by child components may break. If the caller has the information, forward it here to preserve URL consistency.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx (1)

37-44: Consider caching the ABI resolution to avoid redundant network calls

resolveContractAbi is executed on every request for non-localhost chains. For popular public contracts this can become an expensive hot-path.
If the ABI is immutable, wrap the call in unstable_cache (Next.js) or your in-house cache util with a sensible revalidation time.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx (1)

39-45: Add an explicit return after redirect for readability & type-safety

redirectToContractLandingPage presumably ends the response (calls redirect).
Adding return makes the control flow obvious to readers and silences potential lint rules complaining about “function continues after redirect”.

   redirectToContractLandingPage({
     chainIdOrSlug: props.chainIdOrSlug,
     contractAddress: props.contractAddress,
     projectMeta: props.projectMeta,
   });
+  return null; // unreachable – satisfies TS / ESLint
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx (1)

37-39: Cache heavy metadata look-ups

Similar to the explorer page, getContractPageMetadata can be expensive. Wrapping it in a cache layer (or passing a cached result down from a higher level) will reduce latency for frequently visited token pages.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (1)

53-62: Improve error handling in checkDefaultFeeConfig function.

The empty catch block silently swallows all errors, which could hide important issues like network failures or contract interaction errors. Consider logging the error or handling specific error types.

async function checkDefaultFeeConfig(contract: ThirdwebContract) {
  let hasDefaultFeeConfig = true;
  try {
    const feeInfo = await getPlatformFeeInfo({ contract });
    hasDefaultFeeConfig =
      feeInfo[0].toLowerCase() === DEFAULT_FEE_RECIPIENT.toLowerCase();
-  } catch {}
+  } catch (error) {
+    console.warn("Failed to check default fee config:", error);
+    // Assume default config on error
+  }

  return hasDefaultFeeConfig;
}
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx (1)

50-73: Consider adding an explicit return type to getSelectors

Typing the helper improves IntelliSense for callers and prevents accidental shape changes:

-async function getSelectors(contract: ThirdwebContract) {
+async function getSelectors(
+  contract: ThirdwebContract,
+): Promise<{
+  writeFnSelectorToName: Record<string, string>;
+  eventSelectorToName: Record<string, string>;
+}> {

Not mandatory but a low-effort win for maintainability.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (2)

125-165: Consider making default chains configurable

The hardcoded list of default chains is comprehensive but may need updates as new chains are supported. Consider making this configurable or fetching from a centralized source.

- const defaultChains = [
-   1, 137, 8453, 10, 42161, 11155111, 84532, 11155420, 421614,
- ];
+ const defaultChains = await getSupportedChainIds(); // or from config

213-216: Consider type safety for decoded function data

The decodedData is typed as any which bypasses type safety. Consider using proper typing or at least add runtime validation.

- // biome-ignore lint/suspicious/noExplicitAny: FIXME
- const decodedData: any = await decodeFunctionData({
+ const decodedData: unknown = await decodeFunctionData({
   contract: serverContract,
   data: initializeData,
 });
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (2)

1-21: Consider organizing imports and using path aliases for better maintainability.

The imports are functional but could be better organized. The import on line 13 is particularly long and could benefit from path aliasing.

Consider grouping imports by source (external libraries, internal utilities, components) and using path aliases:

+// External libraries
 import type { Metadata } from "next";
 import { notFound } from "next/navigation";
 import { getContractMetadata } from "thirdweb/extensions/common";
 import { isAddress, isContractDeployed } from "thirdweb/utils";
+
+// API and utilities
 import { getProjects } from "@/api/projects";
 import { getTeams } from "@/api/team";
+import { getAuthTokenWalletAddress } from "@/api/lib/getAuthToken";
 import { resolveFunctionSelectors } from "lib/selectors";
 import { shortenIfAddress } from "utils/usedapp-external";
+
+// Types
 import type { MinimalTeamsAndProjects } from "components/contract-components/contract-deploy-form/add-to-project-card";
-import type { ProjectMeta } from "../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+
+// Components and layout utilities
 import { NebulaChatButton } from "../../../../../nebula-app/(app)/components/FloatingChat/FloatingChat";
 import { examplePrompts } from "../../../../../nebula-app/(app)/data/examplePrompts";
-import { getAuthTokenWalletAddress } from "../../../../api/lib/getAuthToken";

186-206: Consider refactoring the contract type detection and description generation.

The logic for determining contract types and generating descriptions could be more maintainable with a cleaner structure.

+const generateContractDescription = (
+  contractDisplayName: string, 
+  cleanedChainName: string, 
+  contractTypes: { isERC721: boolean; isERC1155: boolean; isERC20: boolean }
+) => {
+  const baseText = `View tokens, source code, transactions, balances, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}`;
+  
+  if (contractTypes.isERC721 || contractTypes.isERC1155) {
+    return `View tokens, source code, transactions, balances, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}.`;
+  } else if (contractTypes.isERC20) {
+    return `View ERC20 tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}`;
+  } else {
+    return `View tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}`;
+  }
+};

    const { isERC1155, isERC20, isERC721 } = supportedERCs(functionSelectors);
    
    const contractDisplayName = `${contractMetadata.name}${
      contractMetadata.symbol ? ` (${contractMetadata.symbol})` : ""
    }`;

    const cleanedChainName = info?.chainMetadata?.name
      .replace("Mainnet", "")
      .replace("Testnet", "")
      .trim();

    const title = `${contractDisplayName} | ${cleanedChainName} Smart Contract`;
-    let description = "";
-
-    if (isERC721 || isERC1155) {
-      description = `View tokens, source code, transactions, balances, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}.`;
-    } else if (isERC20) {
-      description = `View ERC20 tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}`;
-    } else {
-      description = `View tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract  on ${cleanedChainName}`;
-    }
+    const description = generateContractDescription(contractDisplayName, cleanedChainName, { isERC721, isERC1155, isERC20 });
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx (1)

4-4: Consider using a more maintainable import path.

The current import path for ProjectMeta is very long and brittle. Consider creating a barrel export or alias to improve maintainability.

-import type { ProjectMeta } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/app/(app)/(dashboard)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";

Or create a shared types file closer to the consuming components.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f6e73a and 5f65eea.

📒 Files selected for processing (107)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/ContractDirectListingsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/contract-page-path.ts (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageSidebarLinks.ts (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-table.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/opengraph-image.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx (7 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]/overview/components/BuildYourApp.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/LatestEvents.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx (11 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/NFTDetails.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/PermissionsTable.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/contract-overview-page.client.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/ContractProposalsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/ContractSplitPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts (1 hunks)
  • apps/dashboard/src/app/(app)/account/contracts/_components/DeployedContractsPage.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/api/lib/getAuthToken.ts (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/contracts/page.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/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/english-auctions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account-permissions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/accounts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/analytics/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/claim-conditions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/code/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/cross-chain/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/events/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/modules/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/[tokenId]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/permissions/page.tsx (1 hunks)
⛔ Files not processed due to max files limit (11)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/proposals/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/settings/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/sources/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/split/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/tokens/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts
  • apps/dashboard/src/components/contract-components/tables/cells.tsx
  • apps/dashboard/src/components/contract-components/tables/contract-table.stories.tsx
  • apps/dashboard/src/components/contract-components/tables/contract-table.tsx
  • apps/dashboard/src/components/smart-wallets/AccountFactories/factory-contracts.tsx
✅ Files skipped from review due to trivial changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/opengraph-image.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/code/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/analytics/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/english-auctions/page.tsx
🧰 Additional context used
🧠 Learnings (4)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
🔇 Additional comments (129)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/ContractSplitPage.client.tsx (1)

13-13: LGTM: Correct implementation of projectMeta prop propagation

The component correctly accepts the new projectMeta prop and passes it to the RedirectToContractOverview component when split functionality is not supported. This aligns with the PR objectives of incorporating project context throughout the contract pages.

Also applies to: 26-31

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx (1)

13-13: LGTM: Correct implementation of projectMeta prop propagation

The component correctly accepts the new projectMeta prop and passes it to the RedirectToContractOverview component when the contract is not a modular core. This follows the consistent pattern of propagating project context throughout the application.

Also applies to: 26-31

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx (1)

11-11: LGTM: Proper prop threading for project context

The component correctly extends its interface to accept projectMeta, properly destructures it from props, and passes it down to the NFTCards component. This enables project-aware URL generation and navigation throughout the NFT display functionality.

Also applies to: 17-17, 30-30

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.client.tsx (1)

14-14: LGTM: Clean integration of project context

The component correctly accepts the projectMeta prop and passes it to the ContractPermissionsPage component. This enables the permissions page to generate project-aware URLs and maintain consistent navigation within the team/project context.

Also applies to: 28-28

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx (1)

15-15: LGTM! Consistent prop threading pattern.

The addition of projectMeta prop and its propagation to child components follows a consistent pattern across the codebase. The optional typing (ProjectMeta | undefined) maintains backward compatibility.

Also applies to: 28-33, 42-42

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/contracts/page.tsx (1)

45-46: LGTM! Proper context propagation.

Adding teamSlug and projectSlug props to DeployedContractsPage provides necessary team/project context for the component. The values are correctly sourced from the already destructured params object.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/ContractProposalsPage.client.tsx (1)

13-13: LGTM! Consistent pattern implementation.

The addition of projectMeta prop and its usage in the redirect scenario maintains consistency with the broader refactoring effort.

Also applies to: 26-31

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx (1)

13-13: LGTM! Proper conditional rendering with context.

The implementation correctly passes projectMeta to RedirectToContractOverview when claim conditions are not supported, maintaining consistency with the overall refactoring pattern.

Also applies to: 32-37

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-table.tsx (4)

19-20: LGTM! Consistent import pattern for project metadata.

The imports for ProjectMeta type and buildContractPagePath utility follow the established pattern across the codebase.


41-44: LGTM! Proper prop interface extension.

The addition of the optional projectMeta prop to the interface is correctly typed and follows the established pattern.


46-49: LGTM! Clean component signature update.

The component destructuring properly includes the new projectMeta prop while maintaining readability.


101-107: Excellent improvement to URL generation consistency.

The replacement of manual URL construction with buildContractPagePath centralizes route generation logic and ensures consistent URL patterns across the application. This improves maintainability and reduces the risk of URL inconsistencies.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx (3)

14-15: LGTM! Consistent import pattern.

The imports for ProjectMeta type and buildContractPagePath utility maintain consistency with other components in the refactor.


26-26: LGTM! Proper prop addition.

The projectMeta prop is correctly typed and follows the established optional pattern.


91-96: Excellent centralized URL generation.

The use of buildContractPagePath with the /analytics subpath maintains consistency with the routing pattern and improves maintainability by centralizing URL generation logic.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/NFTDetails.tsx (5)

10-12: LGTM! Consistent import pattern.

The imports for ProjectMeta type and buildContractPagePath utility maintain consistency across the refactor.


19-19: LGTM! Proper interface extension.

The addition of the optional projectMeta prop to NFTDetailsProps follows the established typing pattern.


27-27: LGTM! Clean component signature.

The component destructuring properly includes the new projectMeta prop.


29-34: Excellent centralized URL generation.

The replacement of manual URL construction with buildContractPagePath ensures consistent routing patterns and improves maintainability.


70-70: LGTM! Proper prop threading.

The projectMeta prop is correctly passed down to the NFTCards component, maintaining the context flow throughout the component hierarchy.

apps/dashboard/src/app/(app)/api/lib/getAuthToken.ts (1)

32-42: Excellent API improvement for team context flexibility.

The modification to accept an optional teamId parameter provides better control over team context while maintaining backward compatibility through the cookie fallback. The conditional logic properly prioritizes the explicit parameter over the stored cookie value.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.tsx (1)

6-6: LGTM! Clean integration of projectMeta prop

The changes correctly extend the component to accept and propagate the projectMeta prop. The type is properly imported, the interface is updated appropriately, and the prop is correctly passed down to the AccountsTable component.

Also applies to: 14-14, 20-20, 49-49

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.tsx (2)

15-16: LGTM! Proper integration of projectMeta prop

The addition of projectMeta prop and corresponding import are correctly implemented, following the established pattern throughout the codebase.

Also applies to: 25-25, 50-50


54-63: Excellent refactoring to centralized URL generation

Replacing hardcoded URL construction with the buildContractPagePath utility is a great improvement. This approach:

  • Centralizes URL logic for better maintainability
  • Ensures consistent URL structure across components
  • Properly handles project metadata for dynamic routing
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/LatestEvents.tsx (1)

25-26: LGTM! Consistent implementation of dynamic URL generation

The changes properly integrate the projectMeta prop and utilize the buildContractPagePath utility for dynamic URL construction. The implementation:

  • Correctly imports required types and utilities
  • Follows the established pattern from other components
  • Maintains clean separation between logic and UI components

Also applies to: 32-32, 37-42, 48-48

apps/dashboard/src/app/(app)/account/contracts/_components/DeployedContractsPage.tsx (1)

15-16: LGTM! Proper propagation of team and project context

The changes correctly add teamSlug and projectSlug props to both the main component and async function, then properly forward them to the ContractTable component. While this approach uses separate string props instead of a ProjectMeta object (as seen in other files), it achieves the same goal of propagating team/project context through the component hierarchy.

Also applies to: 44-45, 63-64

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx (2)

41-48: projectMeta should be explicitly optional in runtime as well

Although the prop is typed as ProjectMeta | undefined, later code passes it straight into buildContractPagePath.
If a parent forgets the prop, the builder may receive undefined and still try to dereference fields, causing a runtime error.

Consider:

- projectMeta,
+ projectMeta ?? null, // or handle inside buildContractPagePath

or assert inside buildContractPagePath that projectMeta is defined whenever teamSlug/projectSlug-style URLs are generated.


264-272: Potential double slashes in composed paths

subpath already starts with /events…; buildContractPagePath presumably returns /…/contract without a trailing slash.
Please confirm the util never appends a trailing /, otherwise ${basePath}/events will render as …//events.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx (1)

24-30: Prop-plumbing looks correct

projectMeta is forwarded to RedirectToContractOverview, preserving the new routing context while keeping the existing logic intact.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/BuildYourApp.tsx (2)

13-18: Guard against double slashes in codePath

subpath is passed as "/code" (leading slash). If buildContractPagePath naïvely concatenates strings, the resulting URL could contain a double //. Please ensure the helper normalises slashes or pass "code" here.


30-31: Good replacement of hard-coded path

Using buildContractPagePath centralises URL logic and prevents future drift. Nice!

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/page.tsx (1)

5-9: ⚠️ Potential issue

Type mismatch: params should not be a Promise

Next.js supplies params as a plain object, not a promise. Declaring it as Promise<…> compiles but will break type-safety and may confuse future readers.

-export default async function Page(props: {
-  params: Promise<PublicContractPageParams>;
-}) {
-  const [params, account] = await Promise.all([props.params, getRawAccount()]);
+export default async function Page(props: {
+  params: PublicContractPageParams;
+}) {
+  const params = props.params;
+  const account = await getRawAccount();
⛔ Skipped due to learnings
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx (1)

1-15: LGTM! Clean refactoring to shared component architecture.

This refactoring effectively centralizes the complex contract page logic into SharedContractAccountPermissionsPage, making the route handler much cleaner and more maintainable. The pattern of passing projectMeta as undefined is appropriate for public contract pages that exist outside of a project context.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx (3)

7-9: Improved import organization.

Good refactoring to replace ThirdwebClient import with ProjectMeta import, reflecting the actual prop requirements of the component.


20-20: Better prop interface design.

Replacing the redundant client prop with projectMeta makes the interface cleaner since the client is already available through contract.client.


50-60: Consistent prop usage improvements.

The changes correctly:

  • Pass projectMeta to enable project-aware functionality
  • Use contract.client instead of the redundant separate client prop

This eliminates prop duplication while adding the necessary project context.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx (4)

4-4: Consistent type import pattern.

The ProjectMeta import follows the same pattern established across other contract client components.


13-13: Proper optional prop addition.

Adding projectMeta as an optional prop maintains backward compatibility while enabling project-aware functionality.


28-33: Correct prop propagation for redirects.

Ensuring RedirectToContractOverview receives projectMeta enables proper project-aware URL generation during redirects.


42-42: Complete prop forwarding.

The projectMeta prop is correctly passed to ContractNFTPage, completing the data flow through the component hierarchy.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1)

1-18: LGTM! Good architectural refactoring.

The refactoring successfully moves complex logic to a shared component (SharedDirectListingsPage) while maintaining the same functionality. The simplified page component now only handles data fetching and delegates rendering logic to the shared component. Type usage with PublicContractPageParams is correct and prop passing is consistent.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx (2)

5-7: LGTM! Consistent type imports for project context.

The import changes correctly replace ThirdwebClient with ProjectMeta to support the new project-aware routing architecture.


19-19: LGTM! Proper prop threading for project metadata.

The prop type change from client: ThirdwebClient to projectMeta: ProjectMeta | undefined and its usage in getContractPageSidebarLinks correctly propagates project context for URL generation and navigation.

Also applies to: 43-43

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx (2)

9-14: LGTM! Proper variable naming and error handling.

The variable naming correctly uses project instead of team (addressing past review feedback), and the 404 handling for missing projects is appropriate.


21-25:

❓ Verification inconclusive

Verify projectMeta field mappings.

The projectMeta object mixes data sources (project object and params). Please verify that project.teamId is the correct field and that the mapping is consistent with other similar pages.


🏁 Script executed:

#!/bin/bash
# Check the Project type definition and teamId field usage
ast-grep --pattern 'interface Project {
  $$$
  teamId: $_
  $$$
}'

# Check how projectMeta is constructed in other team/project pages
rg -A 5 "projectMeta.*{" --type ts

Length of output: 198


🏁 Script executed:

#!/bin/bash
# Locate the Project interface declaration to confirm the exact field name
rg "interface Project\\b" -A5

# Find how projectMeta is assembled elsewhere in TSX pages to verify consistency
rg "projectMeta\\s*[:=]\\s*\\{" -A5 --type tsx

Length of output: 104


Confirm projectMeta mapping consistency

I couldn’t locate a definitive Project type declaration or other projectMeta usages in the repo, so please verify the following:

  • In your Project interface (e.g. in src/lib/types.ts), ensure teamId is the intended identifier and there isn’t a teamSlug property on the project object.
  • Across other pages that build a projectMeta object, confirm they map the same fields (project.teamIdteamId, params.team_slugteamSlug, etc.).
  • If any pages use project.teamSlug instead or source these values differently, update the snippet in
    apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx
    (lines 21–25) to match the agreed mapping.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.tsx (1)

4-4: LGTM! Consistent project metadata propagation.

The addition of ProjectMeta prop and its propagation through the component hierarchy is well-implemented. The optional type (ProjectMeta | undefined) correctly handles both public and project-scoped contract pages.

Also applies to: 20-20, 28-28, 113-113

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx (1)

5-8: 🛠️ Refactor suggestion

⚠️ Potential issue

params should not be typed as Promise<…>

Next JS passes props.params synchronously; wrapping it in Promise breaks the contract with the framework, forces a superfluous await, and may trigger type-narrowing issues elsewhere (e.g. when re-exported).

-export default async function Page(props: {
-  params: Promise<PublicContractPageParams>;
-}) {
-  const [params, account] = await Promise.all([props.params, getRawAccount()]);
+export default async function Page(props: {
+  params: PublicContractPageParams;
+}) {
+  const [account] = await Promise.all([getRawAccount()]);
+  const { contractAddress, chain_id } = props.params;

You still keep the concurrency benefit while respecting the official signature.

⛔ Skipped due to learnings
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/cross-chain/page.tsx (1)

1-27: LGTM! Clean implementation following established patterns.

The page component correctly implements the project-specific contract route pattern:

  • Proper async parameter handling
  • Project validation with 404 fallback
  • Consistent projectMeta structure passed to shared component

The implementation follows the same pattern as other project-specific contract pages, ensuring consistency across the codebase.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account-permissions/page.tsx (1)

1-27: LGTM! Consistent implementation with cross-chain page.

The implementation follows the established pattern perfectly:

  • Proper error handling with notFound() for missing projects
  • Consistent projectMeta structure (teamId, projectSlug, teamSlug)
  • Clean separation of concerns with shared component delegation

One minor observation: The projectMeta object property order differs slightly from the cross-chain page (teamId first vs projectSlug first), but this doesn't affect functionality.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx (3)

2-3: LGTM! Good use of shared component pattern.

The refactor successfully moves complex business logic to the shared component while maintaining the correct parameter types (PublicContractPageParams) for the public contract route.


8-8: Efficient concurrent data fetching.

Good use of Promise.all() to fetch parameters and account data concurrently, improving page load performance.


11-16: Correct projectMeta handling for public routes.

Setting projectMeta={undefined} is appropriate for public contract routes that don't operate within a specific project context. This maintains consistency with the shared component interface while clearly indicating the route type.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx (3)

4-4: Correct import path for ProjectMeta type.

The import path correctly references the project-specific contract types, ensuring type consistency across the project-aware components.


10-14: Proper prop interface extension.

The addition of the optional projectMeta prop maintains backward compatibility while enabling project-aware functionality. The type definition correctly allows for undefined values.


26-31: Consistent prop threading to redirect component.

The projectMeta prop is correctly passed through to RedirectToContractOverview, enabling project-aware redirects when English auctions are not supported. This maintains the component's existing redirect logic while adding project context.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (2)

8-12: LGTM! Function signature updated correctly for team/project context.

The parameter renaming from chain_id to chainIdOrSlug aligns with the routing changes, and adding the optional teamId parameter enables team-aware client initialization.


35-37: Team context properly passed to client initialization.

The teamId is correctly passed to getUserThirdwebClient to ensure the client has the appropriate team context for authentication and permissions.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx (2)

6-14: Proper async parameter handling and error handling.

The implementation correctly awaits the params Promise (as noted in the retrieved learning) and handles the case where the project is not found with notFound().


20-24: ProjectMeta object construction is correct.

The projectMeta object properly maps the project data and route parameters to provide team and project context to the shared component.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (1)

25-25: Hardcoded isLoggedIn value is appropriate.

Setting isLoggedIn={true} is correct for team/project pages since users must be authenticated to access these routes.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx (1)

5-9:

❌ Incorrect review comment

Avoid wrapping params in a Promise – keep the signature aligned with Next JS conventions

params is synchronously provided by the routing layer ({ [segment: string]: string }).
Typing it as Promise<…> forces every consumer to await a non-thenable object, produces confusing IntelliSense, and hides genuine async work inside the component.

-export default async function Page(props: {
-  params: Promise<PublicContractPageParams>;
-}) {
-  const params = await props.params;
+export default function Page(props: {
+  params: PublicContractPageParams;
+}) {
+  const { params } = props;

This change:

  1. Removes an unnecessary await.
  2. Keeps the component a React server component (it can still be async if additional awaits are required later).

Follow-up: update the type in PublicContractPageParams consumers across the codebase.


🏁 Script executed:

#!/bin/bash
# Search for Page components and their props signature
rg -n "export default async function Page" -A 5
rg -n "params: Promise" -A 3

Length of output: 66199


Keep params as a Promise—this matches our existing conventions
The codebase consistently types and awaits props.params (and props.searchParams) as Promise<…> across all App-Router pages to handle cases where Next.js provides these as thenables (see prior fix in insight/webhooks/page.tsx). Removing the Promise wrapper here would break that pattern and risk runtime errors. No change needed.

Likely an incorrect or invalid review comment.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/events/page.tsx (1)

10-15: ⚠️ Potential issue

Differentiate “not found” from upstream errors

getProject might throw (network, DB, auth). Treating every thrown error as notFound() will incorrectly surface 404s for 5xx situations and make debugging harder.

-const project = await getProject(params.team_slug, params.project_slug);
-
-if (!project) {
-  notFound();
-}
+let project;
+try {
+  project = await getProject(params.team_slug, params.project_slug);
+  if (!project) {
+    notFound();
+    return; // unreachable but satisfies TS
+  }
+} catch (err) {
+  // re-throw and let the Next.js error boundary convert to 500
+  throw err;
+}

This preserves correct HTTP semantics.

Likely an incorrect or invalid review comment.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/modules/page.tsx (2)

6-14: LGTM! Proper async parameter handling and error handling.

The component correctly awaits the params Promise (consistent with Next.js patterns) and properly handles the case where project data is not found by triggering a 404 response.


16-27: Clean projectMeta construction and component usage.

The projectMeta object is constructed with consistent naming and structure, passing all necessary context to the SharedModulesPage component. The hardcoded isLoggedIn={true} follows the pattern seen in other similar pages.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/contract-overview-page.client.tsx (3)

12-14: Good prop threading pattern.

The component properly accepts the optional projectMeta prop and destructures it for clean usage.


28-30: Consistent prop forwarding.

The projectMeta is correctly passed down to the ContractOverviewPage component, maintaining the data flow chain.


4-4:

✅ Verification successful

Verify the import path for ProjectMeta type.

The import path ../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types seems quite deep and might be fragile to file structure changes.


🏁 Script executed:

#!/bin/bash
# Verify the ProjectMeta type definition exists at the imported path
fd -t f "types.ts" apps/dashboard/src/app | grep "team.*project_slug.*contract" | head -5

# Check if there's a more centralized type definition
rg -A 5 "type ProjectMeta" apps/dashboard/src

Length of output: 907


ProjectMeta import path is valid

Verified that ProjectMeta is defined in
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts
and there’s no centralized export for it. No changes required.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx (2)

7-8: Good imports for type safety and URL utility.

The imports for ProjectMeta type and buildContractPagePath utility support the refactoring to centralized URL building.


16-16: Proper optional prop typing.

The projectMeta prop is correctly typed as optional, maintaining backward compatibility.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx (1)

16-27: LGTM! Clean component usage with proper projectMeta construction.

The SharedExplorerPage is called with all necessary props and the projectMeta object follows the established pattern.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx (1)

5-8: ⚠️ Potential issue

params should not be typed/handled as a Promise in a route page component

Next.js (>=13) injects params synchronously. Typing it as Promise<…> and awaiting it:

params: Promise<PublicContractPageParams>;

const [params, account] = await Promise.all([props.params, getRawAccount()]);

① Produces an incorrect type that will compile only because of await abuse, masking errors at call-sites.
② Adds an unnecessary micro-task tick (Promise.resolve) even if the object is already available.
③ Breaks the contract with Next.js – in runtime, props.params will be a plain object, not a promise; accidental double‐awaits can lead to subtle bugs when the object contains getters (e.g. edge runtimes).

Suggested fix:

-export default async function Page(props: {
-  params: Promise<PublicContractPageParams>;
-}) {
-  const [params, account] = await Promise.all([props.params, getRawAccount()]);
+export default async function Page({
+  params,
+}: {
+  params: PublicContractPageParams;
+}) {
+  const account = await getRawAccount();
⛔ Skipped due to learnings
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx (1)

6-7: LGTM! Good refactor to use centralized URL generation.

The changes correctly implement the projectMeta prop pattern and replace hardcoded URL construction with the buildContractPagePath utility. This improves consistency and maintainability across the dashboard.

Also applies to: 34-34, 42-42, 94-99

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/permissions/page.tsx (1)

10-10:

✅ Verification successful

Verify that project.teamId contains the correct team ID.

The variable naming has been improved from previous versions, but I need to verify that project.teamId actually contains the team ID rather than the project ID, given past review concerns about this data structure.

Also applies to: 21-25


🏁 Script executed:

#!/bin/bash
# Description: Verify the Project type structure and teamId field
# Expected: project.teamId should contain the team ID, not project ID

# Search for Project type/interface definitions
rg -A 10 -B 2 "^(export )?(type|interface) Project\b" --type ts --type tsx

# Search for getProject function signature and return type
rg -A 5 "export.*function getProject" --type ts --type tsx

# Look for Project usage in similar files to verify teamId usage pattern
rg -B 2 -A 2 "project\.teamId" --type ts --type tsx

Length of output: 275


🏁 Script executed:

#!/bin/bash
# Search for Project type/interface definitions in TS and TSX files
rg -A 10 -B 2 '^(export )?(type|interface) Project\b' -g '*.ts*'

# Search for getProject function signature and return type
rg -A 5 -B 2 'getProject' -g '*.ts*'

# Search for project.teamId usage across the codebase
rg -B 2 -A 2 'project\.teamId' -g '*.ts*'

Length of output: 69637


🏁 Script executed:

#!/bin/bash
echo "---- apps/dashboard/src/@/api/projects.ts (first 200 lines) ----"
sed -n '1,200p' apps/dashboard/src/@/api/projects.ts

echo
echo "---- Searching for ProjectResponse type definitions ----"
rg -A 5 -B 2 'type ProjectResponse' -g '*.ts*'

Length of output: 2004


Confirmed: project.teamId is the correct team identifier
The Project type aliases ProjectResponse (packages/service-utils/src/core/api.ts), where teamId: string refers to the Team ID. No changes needed.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx (1)

8-44: LGTM! Well-structured shared component with proper error handling.

The implementation follows best practices:

  • Proper error handling with notFound() for missing contract info
  • Graceful ABI resolution error handling
  • Clean separation between localhost and remote chain rendering
  • Consistent with the broader refactoring pattern for shared components
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx (1)

2-2: LGTM! Clean implementation of projectMeta propagation.

The changes correctly add and propagate the optional projectMeta prop through the component tree, enabling all child components to generate project-aware URLs. The implementation is consistent with the broader refactoring pattern.

Also applies to: 24-24, 41-41, 53-53, 62-62, 69-69, 83-83, 93-93, 101-101, 109-109

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/claim-conditions/page.tsx (1)

6-28: LGTM! Clean implementation with proper error handling.

The component follows Next.js app router conventions correctly with async parameter handling and appropriate 404 error handling when the project is not found.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx (1)

8-17: Excellent refactoring! Simplified logic with performance optimization.

The refactoring successfully consolidates complex conditional rendering into a single shared component while maintaining functionality. The use of Promise.all for parallel fetching is a good performance optimization, and explicitly setting projectMeta to undefined clearly indicates this is for public (non-project-scoped) contract access.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx (3)

4-4: Good type import organization.

Importing the ProjectMeta type from the correct location maintains proper module boundaries.


10-13: Proper prop interface extension.

The addition of the optional projectMeta prop correctly supports both project-scoped and public contract contexts.


26-40: Consistent projectMeta propagation.

The projectMeta prop is correctly passed down to both the RedirectToContractOverview and AccountsPage components, maintaining consistency in the component hierarchy.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/accounts/page.tsx (1)

6-28: LGTM! Consistent implementation pattern.

The component follows the same clean pattern as other team/project contract pages with proper async parameter handling and error handling.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx (1)

2-9: ⚠️ Potential issue

props.params should not be typed as a Promise

In a Next JS route segment params is synchronously provided as an object.
Typing it as Promise<PublicContractPageParams> will:

  1. Break type-safety – the framework will supply a PublicContractPageParams, not a Promise.
  2. Force an unnecessary Promise.all wrapper (the spread is already awaited when getRawAccount() resolves).

A minimal fix:

-export default async function Page(props: {
-  params: Promise<PublicContractPageParams>;
-}) {
-  const [params, account] = await Promise.all([props.params, getRawAccount()]);
+export default async function Page(props: {
+  params: PublicContractPageParams;
+}) {
+  const [account] = await Promise.all([getRawAccount()]);
+  const params = props.params;     // already resolved

This also removes an unneeded micro-task and keeps the function signature aligned with other pages.

⛔ Skipped due to learnings
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageSidebarLinks.ts (1)

16-20: Potential double-slash when projectMeta is absent

If buildContractPagePath returns /${chain}/${address} (no trailing slash) the later template strings (${layoutPrefix}/modules, …) are safe.
Verify the helper never inserts a trailing slash to avoid URLs like /0x123///modules.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/page.tsx (2)

4-8: params should not be wrapped in a Promise for Next App Router pages

props.params is synchronously supplied by Next.js, so typing it as Promise<…> and await-ing it is unnecessary and may confuse future readers or tooling (e.g. ESLint rules that rely on the official types).

-export default async function Page(props: {
-  params: Promise<PublicContractPageParams>;
-}) {
-  const params = await props.params;
+export default function Page({ params }: { params: PublicContractPageParams }) {

If the whole component is not otherwise async, the async keyword can also be dropped.
[ suggest_essential_refactor ]


10-12: Parameter name mismatch can break project-aware routing

SharedContractOverviewPage expects chainIdOrSlug, but we are passing params.chain_id, not params.chainIdOrSlug.
If PublicContractPageParams only contains chain_id, downstream code that assumes a slug may misbehave (e.g. wrong breadcrumbs).

Please verify the shape of PublicContractPageParams and either:

-      chainIdOrSlug={params.chain_id}
+      chainIdOrSlug={params.chainIdOrSlug ?? params.chain_id}

or rename the field in the type so that it is unambiguous.
[ request_verification ]

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx (2)

30-32: Avoid deep relative import for shared ProjectMeta type

Importing a type through a 7-level relative path couples unrelated route trees and risks circular-dependency headaches at build time.
Consider hoisting ProjectMeta to a root-level types (or @/types) module:

-import type { ProjectMeta } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
+import type { ProjectMeta } from "@/types/project";

This also improves IntelliSense and future refactors.
[ suggest_optional_refactor ]


118-124: Double-slash risk in buildContractPagePath

subpath: "/nfts" already starts with a slash.
If buildContractPagePath concatenates with / (common), the final URL will contain //nfts.

-  subpath: "/nfts",
+  subpath: "nfts",

Please run a quick check (unit test or console.log) to ensure the generated path is correct.
[ request_verification ]

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/[tokenId]/page.tsx (2)

24-27: isLoggedIn hard-coded to true may expose privileged UI/actions

SharedNFTTokenPage likely shows mint/burn buttons or owner-only data when isLoggedIn is true.
Hard-coding this value means unauthenticated users can see or attempt actions they shouldn’t.

Retrieve the actual auth state (session/token) instead:

-      isLoggedIn={true}
+      isLoggedIn={Boolean(await getAuthToken())}

(or pass it down from a higher layout where auth is already resolved).
[ raise_critical_issue ]


6-13: Same Promise<…> pattern as above – reconsider

As noted in the public-route file, params is delivered synchronously. Using Promise<…> is non-idiomatic and should be removed unless you have a custom loader that actually returns a promise.
[ duplicate_comment ]

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx (1)

151-153: Forwarding new slug props looks good

FactoryContracts now receives teamSlug/projectSlug; this propagates context required by downstream pages without altering existing logic. 👍

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1)

14-19: Consider forwarding projectId alongside teamId

getContractPageParamsInfo receives only teamId.
Other shared pages pass both teamId and projectId, enabling stricter project-scoped look-ups. If that helper expects or benefits from projectId, this omission could surface as subtle auth/visibility bugs.

Please double-check the helper’s signature and include projectId: props.projectMeta?.projectId when applicable.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx (3)

68-70: Prop drilling looks okay, but watch for duplication

teamSlug / projectSlug are now forwarded to AssetsPageAsync. Make sure the child component (and any further descendants) actually declare these props; otherwise TypeScript will silently allow the extra fields but they will be unused.


97-99: Same observation for AssetsPageAsync signature

The async helper now accepts the two new slug props – good. Verify that callers other than this file were updated; otherwise they will fail type-checking.


116-118: Propagation into ContractTable looks correct

ContractTable now receives both IDs and slugs, enabling it to construct project-aware links. Nice incremental improvement.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx (1)

5-9: ⚠️ Potential issue

Incorrect Promise typing on params

As in the assets page, params is synchronously provided by Next 13/14. Typing it as Promise<…> forces unnecessary await logic and could mask real typing errors.

-export default async function Page(props: {
-  params: Promise<PublicContractPageParams>;
-}) {
-  const [params, account] = await Promise.all([props.params, getRawAccount()]);
+export default async function Page(props: {
+  params: PublicContractPageParams;
+}) {
+  const [account] = await Promise.all([getRawAccount()]);
+  const { params } = props;

Adjust the destructuring accordingly.

⛔ Skipped due to learnings
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx (1)

5-23: LGTM! Clean refactoring to shared component pattern.

The simplification to delegate to SharedNFTTokenPage follows the established architectural pattern. The hardcoded projectMeta={undefined} is appropriate for this non-team/project scoped route.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx (1)

29-33: LGTM! ProjectMeta is correctly implemented.

The client component correctly receives projectMeta from props, resolving any previous TODO concerns.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx (1)

9-53: LGTM! Well-structured shared component following established patterns.

The component correctly handles contract info fetching, localhost detection, metadata validation, and conditional rendering/redirection.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (1)

11-51: Well-structured shared component with good separation of concerns.

The component follows React server component best practices with proper data fetching, error handling via notFound(), and conditional rendering based on chain type. The concurrent fetching pattern with Promise.all is efficient.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx (1)

9-54: Correctly implemented shared accounts page component.

The component properly handles contract info fetching, localhost rendering, and factory support validation. The previous issue with projectMeta={undefined} has been correctly fixed - line 32 now passes props.projectMeta as expected.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx (1)

9-57: Well-implemented shared account page component.

The component correctly follows the established pattern with proper data fetching, localhost handling, account validation, and conditional rendering. The props are appropriately passed to child components including chainMetadata and projectMeta.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx (2)

46-46: 💡 Verification agent

🧩 Analysis chain

Inconsistent projectMeta prop passing between client and server components.

The server-side AccountSigners component (line 46) doesn't receive the projectMeta prop, while the client-side AccountSignersClient (lines 28-32) does. This inconsistency may affect navigation behavior between localhost and remote chains.


🏁 Script executed:

#!/bin/bash
# Check if AccountSigners component accepts projectMeta prop
ast-grep --pattern 'function AccountSigners($$$) {
  $$$
}'

# Check the component's prop interface
rg -A 10 -B 2 "AccountSigners.*props" apps/dashboard/src/app/\(app\)/\(dashboard\)/\(chain\)

Length of output: 2673


🏁 Script executed:

#!/bin/bash
# Locate server-side AccountSigners file (excluding the client variant)
SERVER_FILE=$(find apps/dashboard/src/app/\(app\)/\(dashboard\)/\(chain\) -type f -name "account-signers.tsx" ! -name "*client.tsx")
echo "Server component file: $SERVER_FILE"
# Show the top of the file to inspect its prop signature
head -n 50 "$SERVER_FILE"

Length of output: 2282


Remove or forward the unused projectMeta prop in AccountSignersClient

The AccountSignersClient component declares a projectMeta prop but never uses or forwards it to AccountSigners. To avoid confusion and possible bugs, either:

  • Remove projectMeta from the AccountSignersClient props interface, since it isn’t consumed;

  • OR ‑

  • If downstream code needs it, update both components to accept and pass it through:

     // AccountSigners.client.tsx
     export function AccountSignersClient(props: {
       contract: ThirdwebContract;
    -  projectMeta: ProjectMeta | undefined;
     }) {
       const metadataQuery = useContractPageMetadata(props.contract);
       …
    -  return <AccountSigners contract={props.contract} />;
    +  return (
    +    <AccountSigners
    +      contract={props.contract}
    +      projectMeta={props.projectMeta}
    +    />
    +  );
     }

    And in components/account-signers.tsx, extend AccountSignersProps accordingly.

Locations to update:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/components/account-signers.tsx

Likely an incorrect or invalid review comment.


9-13:

❌ Incorrect review comment

Verify missing isLoggedIn prop in component signature.

This component's props interface lacks the isLoggedIn prop that other similar shared components include (e.g., SharedContractSettingsPage, SharedAccountsPage). Ensure this omission is intentional.


🏁 Script executed:

#!/bin/bash
# Check if AccountSigners or AccountSignersClient components expect isLoggedIn prop
ast-grep --pattern 'function AccountSigners($$$) {
  $$$
}'

ast-grep --pattern 'function AccountSignersClient($$$) {
  $$$
}'

# Check other shared components for isLoggedIn prop pattern
rg -A 3 "isLoggedIn.*boolean" apps/dashboard/src/app/\(app\)/\(dashboard\)/\(chain\)

Length of output: 66713



---

🏁 Script executed:

```shell
#!/bin/bash
set -e

echo "Files in account-permissions directory:"
ls "apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions"

echo
echo "----- shared-account-permissions-page.tsx (lines 1-200) -----"
sed -n '1,200p' "apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx"

echo
echo "----- Searching for AccountSigners definitions -----"
grep -R -n "AccountSigners" "apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions"

Length of output: 4087


Ignore missing isLoggedIn and projectMeta prop suggestions for SharedContractAccountPermissionsPage

Both flagged inconsistencies are false positives:

  • The server-side SharedContractAccountPermissionsPage intentionally only accepts contractAddress, chainIdOrSlug, and projectMeta — it does not need an isLoggedIn prop at this layer.
  • The client component AccountSignersClient takes projectMeta, but the inner <AccountSigners> component’s props interface only declares a contract field. Passing projectMeta there would be a no-op.

No changes are required.

Likely an incorrect or invalid review comment.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx (4)

61-62: LGTM! Proper imports for project context support.

The imports for ProjectMeta type and buildContractPagePath utility are correctly added to support the new project-aware URL generation functionality.


96-106: LGTM! Component signature properly updated.

The DataTable component signature correctly adds the optional projectMeta prop, maintaining backward compatibility while enabling project-aware navigation.


242-252: LGTM! Consistent URL generation in network links.

The network column links now use buildContractPagePath to generate URLs that include project metadata when available, replacing the previous hardcoded approach. This ensures consistent navigation behavior across the dashboard.


420-427: LGTM! Post-deployment contract links use centralized URL generation.

The post-deployment contract view link correctly uses buildContractPagePath to generate project-aware URLs, ensuring users are directed to the appropriate project-scoped contract page after successful deployment.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx (3)

9-14: LGTM! Well-structured component interface.

The component signature properly accepts all necessary props including projectMeta for project-aware navigation and isLoggedIn for authentication state.


15-23: LGTM! Proper contract validation and error handling.

The component correctly uses getContractPageParamsInfo to validate contract parameters and properly handles the case where contract info is not found by triggering a 404 response.


26-34: LGTM! Client component receives project context.

The localhost branch correctly passes projectMeta to the client component, enabling project-aware navigation in development environments.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (4)

10-14: LGTM! Consistent component interface.

The component signature follows the established pattern and properly includes projectMeta for project-aware navigation.


15-23: LGTM! Proper contract validation and error handling.

The component correctly validates contract parameters and handles missing contract info with appropriate 404 response.


27-35: LGTM! Client component properly configured.

The localhost branch correctly passes all necessary props including projectMeta, chainMetadata, and contract to the client component.


39-60: LGTM! Comprehensive server component configuration.

The server component receives extensive metadata and properly includes projectMeta for consistent navigation behavior. The ErrorBoundary wrapper around PublishedBy provides good fault tolerance.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/page.tsx (2)

1-2: LGTM! Proper imports for simplified implementation.

The imports are correctly updated to use PublicContractPageParams type and the new SharedCrossChainPage component.


5-15: LGTM! Clean simplification with proper prop passing.

The page implementation is correctly simplified to use the shared component pattern. Passing undefined for projectMeta is appropriate for public contract pages that don't have project context.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1)

46-53:

✅ Verification successful

Verify projectMeta propagation in client component

The projectMeta prop is now correctly passed to TokenIdPageClient. Ensure the client component properly handles and forwards this metadata for consistent navigation.


🏁 Script executed:

#!/bin/bash
# Verify TokenIdPageClient accepts and uses projectMeta prop
ast-grep --pattern 'function TokenIdPageClient($$$) {
  $$$
}'

Length of output: 5754


projectMeta correctly propagated in TokenIdPageClient
Verified that TokenIdPageClient accepts a projectMeta prop and forwards it to both <RedirectToContractOverview> and <TokenIdPage>. No further changes required.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx (2)

16-23: Excellent refactor: Logic centralized in shared components

This simplification moves complex validation, data fetching, and conditional rendering logic to SharedContractLayout, improving maintainability and reducing code duplication across contract pages.


33-37: Clean delegation to shared metadata generation

The metadata generation is now properly delegated to generateContractLayoutMetadata, removing duplicate logic and ensuring consistency across contract layouts.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (1)

28-37: Good contract validation pattern

The component properly fetches contract info with team context and handles the not found case appropriately.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (6)

29-31: LGTM! Proper address validation with early return.

The address validation using isAddress with early return via notFound() is a good security practice that prevents invalid addresses from being processed further.


33-41: Excellent use of Promise.all for parallel data fetching.

The parallel execution of independent async operations optimizes performance by reducing total execution time compared to sequential await calls.


67-75: Good error handling in contract validation Promise.all.

The .catch(() => false) on line 72 properly handles potential deployment check failures by defaulting to false, which will trigger the 404 handling below.


130-158: Good error handling and performance optimization in teams/projects fetching.

The function properly handles authentication failures by returning undefined and uses Promise.all to parallelize project fetching for each team. The try-catch ensures graceful degradation when user data is unavailable.


175-180: LGTM! Parallel execution optimizes metadata generation.

Using Promise.all to fetch function selectors and contract metadata concurrently improves performance while maintaining proper error handling.


212-217: Good fallback metadata handling for error cases.

The fallback logic properly handles cases where contract metadata cannot be retrieved, providing sensible defaults using the address and chain information.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx (3)

15-15: Good addition of optional projectMeta prop.

Adding projectMeta as an optional prop maintains backward compatibility while enabling the new team/project context functionality.


31-36: Proper context propagation in redirect flow.

The updated RedirectToContractOverview call correctly passes the projectMeta to maintain team/project context when redirecting users for unsupported ERC standards.


46-46: Consistent prop forwarding to child component.

The projectMeta prop is properly forwarded to the TokenIdPage component, maintaining the data flow pattern established throughout this refactor.

Copy link
Contributor

graphite-app bot commented May 26, 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 introduces enhancements to the handling of contract pages, adding new types for parameters and project metadata, while refactoring existing components to incorporate team and project-specific data.

### Detailed summary
- Added `PublicContractPageParams` and `ProjectContractPageParams` types.
- Introduced `ProjectMeta` type for project metadata.
- Refactored components to accept `teamSlug`, `projectSlug`, and `projectMeta`.
- Updated routing and links to include project-specific paths.
- Enhanced handling of contract page data retrieval and UI rendering.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.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]/explorer/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.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]/split/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.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]/claim-conditions/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.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]/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.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**
  - Enhanced routing to include project and team slugs, enabling project-aware navigation for contract, NFT, marketplace, analytics, permissions, and proposal pages.
  - Passed project metadata (team and project info) throughout various pages and components for contextual consistency.
  - Introduced shared layout and page components for contract overview, NFTs, analytics, permissions, and settings, streamlining the user experience.

- **Refactor**
  - Removed internal data fetching, validation, and conditional rendering from pages, delegating logic to shared components.
  - Updated navigation links and breadcrumbs to dynamically incorporate project and team slugs when available.
  - Centralized metadata and layout generation into utility functions to reduce duplication.

- **Bug Fixes**
  - Improved handling of missing or invalid project/team data by triggering notFound responses appropriately.

- **Chores**
  - Extended component props and interfaces to accept projectMeta objects.
  - Simplified page components to directly render shared components with minimal logic.
  - Updated URL construction to utilize utility functions for project-aware paths.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@graphite-app graphite-app bot force-pushed the 05-24-add_contract_layout_in_team_project branch from 5f65eea to 1247502 Compare May 26, 2025 20:59
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 26, 2025 20:59 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 26, 2025 20:59 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 26, 2025 20:59 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 26, 2025 20:59 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: 1

♻️ Duplicate comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (1)

94-99: Extract the hardcoded AI prompt prefix to improve maintainability.

The contractPromptPrefix is quite long and hardcoded within the component, making it difficult to maintain and test. Consider extracting it to a separate constant or utility function.

+// At the top of the file or in a separate utils file
+const createContractPromptPrefix = (contractAddress: string, chainName: string, chainId: number) => 
+  `A user is viewing the contract address ${contractAddress} on ${chainName} (Chain ID: ${chainId}). Provide a concise summary of this contract's functionalities, such as token minting, staking, or governance mechanisms. Focus on what the contract enables users to do, avoiding transaction execution details unless requested.
+Users may be interested in how to interact with the contract. Outline common interaction patterns, such as claiming rewards, participating in governance, or transferring assets. Emphasize the contract's capabilities without guiding through transaction processes unless asked.
+Provide insights into how the contract is being used. Share information on user engagement, transaction volumes, or integration with other dApps, focusing on the contract's role within the broader ecosystem.
+Users may be considering integrating the contract into their applications. Discuss how this contract's functionalities can be leveraged within different types of dApps, highlighting potential use cases and benefits.
+
+The following is the user's message:`;

-  const contractPromptPrefix = `A user is viewing the contract address ${contractAddress} on ${chainName} (Chain ID: ${chainId}). Provide a concise summary of this contract's functionalities, such as token minting, staking, or governance mechanisms. Focus on what the contract enables users to do, avoiding transaction execution details unless requested.
-Users may be interested in how to interact with the contract. Outline common interaction patterns, such as claiming rewards, participating in governance, or transferring assets. Emphasize the contract's capabilities without guiding through transaction processes unless asked.
-Provide insights into how the contract is being used. Share information on user engagement, transaction volumes, or integration with other dApps, focusing on the contract's role within the broader ecosystem.
-Users may be considering integrating the contract into their applications. Discuss how this contract's functionalities can be leveraged within different types of dApps, highlighting potential use cases and benefits.
-
-The following is the user's message:`;
+  const contractPromptPrefix = createContractPromptPrefix(contractAddress, chainName, chainId);
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (1)

227-231: ⚠️ Potential issue

Critical bug: Fix the off-by-one error in module index check.

This issue was previously identified but remains unfixed. When findIndex returns 0 (indicating the modules parameter is the first argument), the current ternary check moduleIndex ? evaluates to false, incorrectly setting modules to undefined.

Apply this fix:

-modules = moduleIndex ? decodedData[moduleIndex] : undefined;
+modules = moduleIndex !== -1 ? decodedData[moduleIndex] : undefined;
🧹 Nitpick comments (6)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (2)

203-203: Fix missing semicolon in description string.

The description string is missing a semicolon at the end for consistency with other description strings.

-      description = `View ERC20 tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}`
+      description = `View ERC20 tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}.`;

205-205: Fix double space in description string.

There's an extra space between "contract" and "on" in the description string.

-      description = `View tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract  on ${cleanedChainName}`;
+      description = `View tokens, transactions, balances, source code, and analytics for the ${contractDisplayName} smart contract on ${cleanedChainName}.`;
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (4)

125-127: Extract hardcoded chain IDs to a constant.

The default chains list should be extracted to a named constant for better maintainability and reusability.

+const DEFAULT_CROSS_CHAIN_IDS = [
+  1, 137, 8453, 10, 42161, 11155111, 84532, 11155420, 421614,
+] as const;

-const defaultChains = [
-  1, 137, 8453, 10, 42161, 11155111, 84532, 11155420, 421614,
-];
+const defaultChains = DEFAULT_CROSS_CHAIN_IDS;

99-101: Extract hardcoded address to a named constant.

The CREATE2 factory address should be extracted to a named constant for clarity and maintainability.

+const CREATE2_FACTORY_ADDRESS = "0x4e59b44847b379578588920cA78FbF26c0B4956C";

isDirectDeploy =
  creationTx.to?.toLowerCase() ===
-  "0x4e59b44847b379578588920cA78FbF26c0B4956C".toLowerCase();
+  CREATE2_FACTORY_ADDRESS.toLowerCase();

80-105: Improve error handling specificity.

The current catch block uses a generic console.debug(e) which may not provide sufficient information for debugging deployment issues.

} catch (e) {
-  console.debug(e);
+  console.debug("Failed to fetch contract creation data:", e);
}

129-165: Consider performance optimization for chain deployment checks.

The current implementation checks all chains sequentially with Promise.all, but this could be optimized by implementing request timeouts and potentially batching requests.

Consider adding timeout handling:

const chainsDeployedOn = (
  await Promise.all(
    defaultChains.map(async (c) => {
+     const timeoutPromise = new Promise((_, reject) =>
+       setTimeout(() => reject(new Error('Timeout')), 5000)
+     );
+     
+     return Promise.race([
+       (async () => {
          // eslint-disable-next-line no-restricted-syntax
          const chain = defineChain(c);
          // ... existing logic
+       })(),
+       timeoutPromise
+     ]).catch(() => ({
+       id: c,
+       network: "",
+       chainId: c,
+       status: "NOT_DEPLOYED" as const,
+     }));
    }),
  )
).filter((c) => c.chainId !== serverContract.chain.id);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f65eea and 1247502.

📒 Files selected for processing (107)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/ContractDirectListingsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/contract-page-path.ts (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageSidebarLinks.ts (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-table.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/shared-events-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/opengraph-image.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx (7 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]/overview/components/BuildYourApp.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/LatestEvents.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx (11 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/NFTDetails.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/PermissionsTable.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/contract-overview-page.client.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/ContractProposalsPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/ContractSplitPage.client.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts (1 hunks)
  • apps/dashboard/src/app/(app)/account/contracts/_components/DeployedContractsPage.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/api/lib/getAuthToken.ts (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/contracts/page.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/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/english-auctions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account-permissions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/accounts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/analytics/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/claim-conditions/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/code/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/cross-chain/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/events/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/modules/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/[tokenId]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/permissions/page.tsx (1 hunks)
⛔ Files not processed due to max files limit (11)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/proposals/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/settings/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/sources/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/split/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/tokens/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils.ts
  • apps/dashboard/src/components/contract-components/tables/cells.tsx
  • apps/dashboard/src/components/contract-components/tables/contract-table.stories.tsx
  • apps/dashboard/src/components/contract-components/tables/contract-table.tsx
  • apps/dashboard/src/components/smart-wallets/AccountFactories/factory-contracts.tsx
✅ Files skipped from review due to trivial changes (1)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts
🚧 Files skipped from review as they are similar to previous changes (95)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/opengraph-image.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/ContractSplitPage.client.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/contracts/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/AccountSigners.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/ContractProposalsPage.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/BuildYourApp.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/analytics/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/code/page.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]/events/shared-events-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/explorer/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/modules/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account-permissions/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/shared-sources-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/cross-chain/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/events/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-table.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx
  • apps/dashboard/src/app/(app)/account/contracts/_components/DeployedContractsPage.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/contract-overview-page.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/PermissionsTable.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/english-auctions/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractFromParams.ts
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/getContractPageSidebarLinks.ts
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/accounts/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/account/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/claim-conditions/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/ContractDirectListingsPage.client.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/LatestEvents.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/shared-code-page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/permissions/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/[tokenId]/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/(marketplace)/direct-listings/page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-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]/tokens/shared-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/NFTDetails.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.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]/shared-overview-page.tsx
  • apps/dashboard/src/app/(app)/api/lib/getAuthToken.ts
  • 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]/split/shared-split-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_utils/contract-page-path.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
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.737Z
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.
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.299Z
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]/accounts/page.tsx (2)
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx:2-10
Timestamp: 2025-05-26T16:28:10.059Z
Learning: In Next.js 14+, the `params` object in page components is always a Promise that needs to be awaited, so the correct typing is `params: Promise<ParamsType>` rather than `params: ParamsType`.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
🧬 Code Graph Analysis (7)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx (3)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts (1)
  • PublicContractPageParams (1-4)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx (1)
  • SharedContractSettingsPage (11-51)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx (3)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts (1)
  • PublicContractPageParams (1-4)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx (1)
  • SharedNFTPage (9-56)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx (3)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts (1)
  • PublicContractPageParams (1-4)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx (1)
  • SharedDirectListingsPage (9-53)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx (3)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts (1)
  • PublicContractPageParams (1-4)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx (1)
  • SharedClaimConditionsPage (9-59)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx (3)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts (1)
  • PublicContractPageParams (1-4)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx (1)
  • SharedNFTTokenPage (11-76)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx (4)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx (1)
  • Page (4-15)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/types.ts (1)
  • PublicContractPageParams (1-4)
apps/dashboard/src/app/(app)/account/settings/getAccount.ts (1)
  • getRawAccount (11-38)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx (1)
  • SharedAccountsPage (9-54)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (2)
  • SharedContractLayout (23-128)
  • generateContractLayoutMetadata (160-218)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx (1)
  • generateMetadata (34-54)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (34)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx (4)

2-3: LGTM: Clean import structure

The imports are well-organized and follow the established pattern seen across other contract pages in the codebase.


6-6: LGTM: Correct Next.js 13+ app router pattern

Using Promise<PublicContractPageParams> aligns with the Next.js 13+ app router where params are promises. This is consistent with the pattern used across other contract pages.


8-8: LGTM: Efficient parallel data fetching

Using Promise.all to fetch params and account data in parallel is a good performance optimization since these are independent operations.


10-16: LGTM: Proper delegation to shared component

The component correctly delegates to SharedClaimConditionsPage with all required props. The explicit projectMeta: undefined is consistent with the pattern for server components as noted in the retrieved learnings. This architectural change successfully moves complex logic (contract validation, metadata checking, conditional rendering) to the shared component, improving maintainability.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx (4)

1-3: LGTM! Clean import structure.

The imports are well-organized and follow the established patterns. The PublicContractPageParams type import and SharedDirectListingsPage component import are appropriate for the refactored architecture.


5-7: Good use of Promise-based params.

The function signature correctly uses Promise<PublicContractPageParams> which aligns with Next.js App Router patterns for async route parameters.


8-8: Excellent concurrent data fetching.

Using Promise.all to fetch both params and getRawAccount() concurrently is a performance optimization that reduces the overall loading time.


10-17: Clean delegation to shared component.

The simplified rendering pattern effectively delegates complex logic to SharedDirectListingsPage. Setting projectMeta={undefined} is appropriate for server components based on the retrieved learnings, and the props match the expected interface from the shared component.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx (4)

2-3: LGTM: Clean import structure following the new pattern.

The imports correctly reference the new type definitions and shared component, aligning with the refactored architecture.


6-6: LGTM: Proper Next.js 15 pattern with Promise-wrapped params.

The component correctly handles the new Next.js 15 pattern where route parameters are wrapped in a Promise, ensuring compatibility with the latest framework conventions.


8-8: LGTM: Efficient concurrent data fetching.

Using Promise.all to fetch both params and account data concurrently is a performance optimization that reduces the overall loading time.


11-17: LGTM: Simplified component following the new architectural pattern.

The component correctly delegates complex logic to SharedNFTPage while maintaining the required props structure. Setting projectMeta to undefined is consistent with the pattern for server components as noted in the retrieved learnings.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx (3)

2-3: Clean import structure for the refactored architecture.

Good use of type imports and the shared component pattern. This follows the established architectural approach across other contract pages in the codebase.


6-8: Excellent use of concurrent data fetching and proper TypeScript types.

The Promise.all approach for fetching both params and account data concurrently is a performance optimization over sequential fetching. The Promise-wrapped params type correctly handles the new parameter structure.


11-17: Well-structured delegation to shared component.

This approach successfully:

  • Centralizes complex contract logic in SharedContractSettingsPage
  • Maintains clean separation of concerns
  • Correctly sets projectMeta={undefined} for this public route (consistent with learned patterns for server-rendered components)
  • Passes all necessary props for proper rendering

The refactoring improves maintainability while supporting the new team/project context features.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx (3)

2-3: LGTM! Clean import structure for the refactored implementation.

The new imports properly support the simplified page structure by bringing in the required type and shared component.


5-7: Correct params typing for Next.js 14+.

The function signature correctly types params as Promise<PublicContractPageParams>, which aligns with Next.js 14+ behavior where params are always promises.


8-16: Excellent refactoring that centralizes contract page logic.

This implementation follows the established pattern across contract pages:

  • Concurrently awaits both params and user account data for optimal performance
  • Delegates all complex logic (contract info fetching, validation, redirects) to SharedAccountsPage
  • Correctly passes projectMeta as undefined for public routes
  • Converts account to boolean for the isLoggedIn prop

This refactoring improves maintainability by eliminating code duplication and centralizing contract page behavior.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx (3)

1-2: LGTM! Clean import structure for the refactored analytics page.

The imports correctly reference the new type definitions and shared component, aligning with the broader refactoring to centralize contract logic.


4-6: Good use of proper TypeScript typing.

The updated parameter type PublicContractPageParams correctly reflects that this is a public contract page (not within a team/project context), which explains why projectMeta will be undefined.


9-13:

✅ Verification successful

Excellent refactoring - complexity moved to shared component.

This is a clean implementation of the refactoring pattern described in the PR objectives. The page now focuses solely on prop passing while the SharedAnalyticsPage handles all the complex contract validation, data fetching, and conditional rendering logic that was previously in this file.

Setting projectMeta={undefined} is appropriate for public contract pages and follows the established pattern from the retrieved learnings.

Let me verify that the shared component properly handles the delegated logic:


🏁 Script executed:

#!/bin/bash
# Description: Verify the SharedAnalyticsPage component handles the moved contract logic
# Expected: The shared component should contain contract validation, data fetching, and error handling

cat "apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx"

Length of output: 2615


✅ Verification complete: SharedAnalyticsPage correctly handles contract validation, data fetching, and error handling. Approving code changes.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx (4)

2-3: LGTM! Clean import structure for the refactored implementation.

The new imports properly support the architectural shift to using shared components and centralized type definitions.


5-11: Correct implementation of Next.js 15 async params pattern.

The Promise wrapper around params properly handles the async nature of route parameters in Next.js 15, and the type intersection correctly extends PublicContractPageParams with the tokenId field.


12-12: Excellent use of concurrent data fetching.

Using Promise.all to fetch params and account data concurrently is an optimal performance improvement since these operations are independent.


14-23: Well-structured delegation to shared component.

The implementation correctly:

  • Passes all required props to SharedNFTTokenPage
  • Sets projectMeta to undefined (consistent with server component patterns per retrieved learnings)
  • Uses proper boolean conversion for isLoggedIn flag
  • Follows the established pattern of delegating complex contract logic to shared components

This clean separation of concerns improves maintainability and code reuse across the dashboard.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx (2)

16-23: LGTM! Clean delegation to shared layout component.

The simplified layout effectively delegates complex contract validation, data fetching, and rendering logic to the SharedContractLayout component. Setting projectMeta={undefined} correctly indicates this route is not within a project context.


33-37: LGTM! Proper metadata generation delegation.

The metadata generation correctly delegates to the shared generateContractLayoutMetadata utility, maintaining consistency across different contract page routes.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx (4)

29-31: LGTM! Proper address validation.

The early validation using isAddress and notFound() correctly handles invalid contract addresses at the entry point.


33-41: LGTM! Efficient parallel data fetching.

The use of Promise.all to fetch contract info, authentication status, and teams/projects data in parallel is efficient and follows best practices.


67-75: LGTM! Well-structured metadata fetching.

The parallel fetching of contract validation, page metadata, and header data is efficient and properly structured.


130-158: LGTM! Robust teams and projects fetching.

The helper function properly handles authentication checks, parallel fetching of team projects, and graceful error handling by returning undefined on failures.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/page.tsx (1)

1-15: LGTM! Clean refactor following the established pattern.

The implementation correctly follows the refactor pattern mentioned in the PR objectives, where complex contract page logic has been moved to shared components. The page properly awaits route parameters and delegates rendering to SharedCrossChainPage with appropriate props.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx (2)

28-32: LGTM! Well-structured component interface.

The component props interface is clean and properly typed with optional projectMeta to support both public and project-scoped contract pages.


257-281: LGTM! Clean component structure and prop passing.

The JSX structure is well-organized with clear section separation and proper prop forwarding to the DataTable component.

Comment on lines +212 to +216
// biome-ignore lint/suspicious/noExplicitAny: FIXME
const decodedData: any = await decodeFunctionData({
contract: serverContract,
data: initializeData,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove or properly type the any annotation.

The decodedData: any violates TypeScript best practices. Consider using proper typing or a more specific type assertion.

-// biome-ignore lint/suspicious/noExplicitAny: FIXME
-const decodedData: any = await decodeFunctionData({
+const decodedData: unknown[] = await decodeFunctionData({
  contract: serverContract,
  data: initializeData,
});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// biome-ignore lint/suspicious/noExplicitAny: FIXME
const decodedData: any = await decodeFunctionData({
contract: serverContract,
data: initializeData,
});
const decodedData: unknown[] = await decodeFunctionData({
contract: serverContract,
data: initializeData,
});
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx
around lines 212 to 216, the variable decodedData is typed as any, which
violates TypeScript best practices. Replace the any type with a more specific
type that matches the expected structure returned by decodeFunctionData, or
define an appropriate interface/type for decodedData to ensure type safety and
clarity.

@graphite-app graphite-app bot merged commit 1247502 into main May 26, 2025
24 checks passed
@graphite-app graphite-app bot deleted the 05-24-add_contract_layout_in_team_project branch May 26, 2025 21:07
@vercel vercel bot temporarily deployed to Production – docs-v2 May 26, 2025 21:07 Inactive
@vercel vercel bot temporarily deployed to Production – thirdweb_playground May 26, 2025 21:07 Inactive
@vercel vercel bot temporarily deployed to Production – login May 26, 2025 21:07 Inactive
@vercel vercel bot temporarily deployed to Production – wallet-ui May 26, 2025 21:07 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