-
Notifications
You must be signed in to change notification settings - Fork 618
[MNY-166] Dashboard: Add Dex Screener charts in public ERC20 token page #8035
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughRemoves the server-side token price API and the TokenStats/PriceChart UI, adds a readonly chainId→DexScreener slug map and a theme-aware DexScreener iframe component, and updates the ERC20 public page layout to conditionally render the DexScreener embed and reorganize surrounding sections. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant ERC20Page as ERC20 Public Page
participant SlugMap as mapChainIdToDexScreenerChainSlug
participant DexComp as DexScreener
participant Theme as next-themes
participant Iframe as DexScreener Iframe
User->>ERC20Page: Navigate to token page
ERC20Page->>SlugMap: lookup(chainId)
alt slug exists
ERC20Page->>DexComp: render(slug, contractAddress)
DexComp->>Theme: read current theme
DexComp->>DexComp: build embed URL (slug, addr, query params, theme)
DexComp->>Iframe: render iframe (ClientOnly)
else slug missing
ERC20Page-->>User: omit DexScreener section
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Pre-merge checks (4 passed, 1 warning)❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests
Comment |
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8035 +/- ##
=======================================
Coverage 56.64% 56.64%
=======================================
Files 904 904
Lines 58755 58755
Branches 4170 4170
=======================================
Hits 33280 33280
Misses 25369 25369
Partials 106 106
🚀 New features to boost your workflow:
|
size-limit report 📦
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (2)
12-29: Use resolvedTheme to avoid flicker; normalize address; memo depsPrevents dark-default flash and redundant reloads when theme=system.
- const { theme } = useTheme(); + const { resolvedTheme } = useTheme(); @@ - const iframeUrl = useMemo(() => { - const resolvedTheme = theme === "light" ? "light" : "dark"; + const iframeUrl = useMemo(() => { + const themeParam = resolvedTheme === "light" ? "light" : "dark"; + const address = props.contractAddress.toLowerCase(); const url = new URL("https://dexscreener.com"); - url.pathname = `${props.chain}/${props.contractAddress}`; + url.pathname = `${props.chain}/${address}`; - url.searchParams.set("chartTheme", resolvedTheme); - url.searchParams.set("theme", resolvedTheme); + url.searchParams.set("chartTheme", themeParam); + url.searchParams.set("theme", themeParam); url.searchParams.set("trades", "1"); @@ - return url.toString(); - }, [theme, props.chain, props.contractAddress]); + return url.toString(); + }, [resolvedTheme, props.chain, props.contractAddress]);
31-36: Minor: defer iframe work and improve a11yLazy-load and make the title more descriptive.
- <iframe - className="w-full h-[500px] lg:h-[1000px] rounded-lg overflow-hidden border bg-card" - src={iframeUrl} - title="DexScreener" - ></iframe> + <iframe + className={props.className ?? "w-full h-[500px] lg:h-[1000px] rounded-lg overflow-hidden border bg-card"} + src={iframeUrl} + title={`DexScreener: ${props.chain}`} + loading="lazy" + referrerPolicy="no-referrer-when-downgrade" + />
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx(3 hunks)
💤 Files with no reviewable changes (2)
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.tsapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsxapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.tsapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsxapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/*(Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
UseNavLinkfor internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Usecn()from@/lib/utilsfor conditional class logic
Use design system tokens (e.g.,bg-card,border-border,text-muted-foreground)
Server Components (Node edge): Start files withimport "server-only";
Client Components (browser): Begin files with'use client';
Always callgetAuthToken()to retrieve JWT from cookies on server side
UseAuthorization: Bearerheader – never embed tokens in URLs
Return typed results (e.g.,Project[],User[]) – avoidany
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stablequeryKeysfor React Query cache hits
ConfigurestaleTime/cacheTimein React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never importposthog-jsin server components
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.tsapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsxapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
apps/{dashboard,playground}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/_(e.g., Button, Input, Tabs, Card)
UseNavLinkfor internal navigation to get active state handling
Use Tailwind CSS for styling; no inline styles
Merge class names withcn()from@/lib/utilsfor conditional classes
Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components must start withimport "server-only"; usenext/headers, server‑only env, heavy data fetching, andredirect()where appropriate
Client Components must start with'use client'; handle interactivity with hooks and browser APIs
Server-side data fetching: callgetAuthToken()from cookies, sendAuthorization: Bearer <token>header, and return typed results (avoidany)
Client-side data fetching: wrap calls in React Query with descriptive, stablequeryKeysand set sensiblestaleTime/cacheTime(≥ 60s default); keep tokens secret via internal routes or server actions
Do not importposthog-jsin server components (client-side only)
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.tsapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsxapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Expose a
classNameprop on the root element of every component
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsxapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧠 Learnings (4)
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
📚 Learning: 2025-08-29T23:44:47.512Z
Learnt from: MananTank
PR: thirdweb-dev/js#7951
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx:38-38
Timestamp: 2025-08-29T23:44:47.512Z
Learning: The ContractPageLayout component in apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx is not the root layout - it's nested within the dashboard layout which already handles footer positioning with min-h-dvh and AppFooter placement. The ContractPageLayout needs flex flex-col grow to properly participate in the parent's flex layout.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsxapps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-05-27T19:55:25.056Z
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts:49-49
Timestamp: 2025-05-27T19:55:25.056Z
Learning: In the ERC20 public pages token price data hook (`useTokenPriceData.ts`), direct array access on `json.data[0]` without optional chaining is intentionally correct and should not be changed to use safety checks.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use the `container` class with a `max-w-7xl` cap for page width consistency.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧬 Code graph analysis (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1)
DexScreenerChainSlug(76-77)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx (1)
PageHeader(7-32)apps/dashboard/src/@/components/ui/background-patterns.tsx (1)
GridPattern(32-86)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1)
mapChainIdToDexScreenerChainSlug(1-74)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1)
DexScreener(40-58)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx (1)
ContractAnalyticsOverview(10-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Lint Packages
- GitHub Check: Unit Tests
- GitHub Check: Size
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)
81-81: Width cap: matches dashboard standardmax-w-7xl is consistent with container guidance.
149-155: LGTM: analytics section placementOrdering after the chart keeps the narrative coherent.
...)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
Show resolved
Hide resolved
...)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
Outdated
Show resolved
Hide resolved
...)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
Show resolved
Hide resolved
...hboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
Show resolved
Hide resolved
...hboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
Show resolved
Hide resolved
.../src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
Show resolved
Hide resolved
.../src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)
105-120: Replace inline style with Tailwind arbitrary propertyInline styles are disallowed in dashboard. Use Tailwind’s arbitrary property for mask-image.
<GridPattern width={30} height={30} x={-1} y={-1} strokeDasharray={"4 2"} - className="text-border dark:text-border/70" - style={{ - maskImage: - "linear-gradient(to bottom right,white,transparent,transparent)", - }} + className='text-border dark:text-border/70 [mask-image:linear-gradient(to_bottom_right,white,transparent,transparent)]' />
135-147: Safer slug lookup and cleaner conditional renderAvoid
inchecks + index assertions. Use a helper and render only when slug exists.- {props.chainMetadata.chainId in mapChainIdToDexScreenerChainSlug && ( - <div className="container max-w-7xl pb-10"> - <DexScreener - chain={ - mapChainIdToDexScreenerChainSlug[ - props.chainMetadata - .chainId as keyof typeof mapChainIdToDexScreenerChainSlug - ] - } - contractAddress={props.clientContract.address} - /> - </div> - )} + {(() => { + const slug = getDexScreenerSlug(props.chainMetadata.chainId); + return slug ? ( + <div className="container max-w-7xl pb-10"> + <DexScreener + chain={slug} + contractAddress={props.clientContract.address} + /> + </div> + ) : null; + })()}
🧹 Nitpick comments (6)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (6)
1-1: Mark this as a Server ComponentAdd the server-only directive to prevent accidental client-side imports.
import "server-only";
15-16: Import the slug helper instead of the raw map (used below)Switch to a typed helper to avoid unsafe index assertions later.
import { DexScreener } from "./_components/dex-screener"; -import { mapChainIdToDexScreenerChainSlug } from "./_components/dex-screener-chains"; +import { getDexScreenerSlug } from "./_components/dex-screener-chains";
131-132: Remove stray whitespace nodeThe {" "} after the closing div renders an unnecessary text node.
- </div>{" "} + </div>
22-27: Add explicit return types for exported/inner functionsMeets the TypeScript guideline for explicit returns.
Example:
export async function ERC20PublicPage(...): Promise<JSX.Element> { /* ... */ } function BuyEmbed(...): JSX.Element { /* ... */ } async function getActiveClaimConditionWithErrorHandler( contract: ThirdwebContract, ): Promise<ActiveClaimCondition | undefined> { /* ... */ }
75-77: Keep boolean semantics for showBuyEmbedPrevent
object | booleantruthy leaks; coerce to boolean.-const showBuyEmbed = isUBSupported || claimConditionMeta; +const showBuyEmbed = isUBSupported || !!claimConditionMeta;
135-147: Helper implementation (in chains file) if not presentIf
getDexScreenerSlugdoesn’t exist yet, add it alongside the map.// apps/dashboard/.../erc20/_components/dex-screener-chains.ts export type DexScreenerChainSlug = (typeof mapChainIdToDexScreenerChainSlug)[keyof typeof mapChainIdToDexScreenerChainSlug]; export function getDexScreenerSlug( chainId: number, ): DexScreenerChainSlug | undefined { return (mapChainIdToDexScreenerChainSlug as Partial< Record<number, DexScreenerChainSlug> >)[chainId]; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx(3 hunks)
💤 Files with no reviewable changes (2)
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/*(Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
UseNavLinkfor internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Usecn()from@/lib/utilsfor conditional class logic
Use design system tokens (e.g.,bg-card,border-border,text-muted-foreground)
Server Components (Node edge): Start files withimport "server-only";
Client Components (browser): Begin files with'use client';
Always callgetAuthToken()to retrieve JWT from cookies on server side
UseAuthorization: Bearerheader – never embed tokens in URLs
Return typed results (e.g.,Project[],User[]) – avoidany
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stablequeryKeysfor React Query cache hits
ConfigurestaleTime/cacheTimein React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never importposthog-jsin server components
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
apps/{dashboard,playground}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/_(e.g., Button, Input, Tabs, Card)
UseNavLinkfor internal navigation to get active state handling
Use Tailwind CSS for styling; no inline styles
Merge class names withcn()from@/lib/utilsfor conditional classes
Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components must start withimport "server-only"; usenext/headers, server‑only env, heavy data fetching, andredirect()where appropriate
Client Components must start with'use client'; handle interactivity with hooks and browser APIs
Server-side data fetching: callgetAuthToken()from cookies, sendAuthorization: Bearer <token>header, and return typed results (avoidany)
Client-side data fetching: wrap calls in React Query with descriptive, stablequeryKeysand set sensiblestaleTime/cacheTime(≥ 60s default); keep tokens secret via internal routes or server actions
Do not importposthog-jsin server components (client-side only)
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Expose a
classNameprop on the root element of every component
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧠 Learnings (11)
📚 Learning: 2025-08-29T23:44:47.512Z
Learnt from: MananTank
PR: thirdweb-dev/js#7951
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx:38-38
Timestamp: 2025-08-29T23:44:47.512Z
Learning: The ContractPageLayout component in apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx is not the root layout - it's nested within the dashboard layout which already handles footer positioning with min-h-dvh and AppFooter placement. The ContractPageLayout needs flex flex-col grow to properly participate in the parent's flex layout.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Tailwind CSS is the styling system – avoid inline styles or CSS modules.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Never hard-code colors – always go through Tailwind variables.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Use Tailwind CSS for styling; no inline styles
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use Tailwind CSS only – no inline styles or CSS modules
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Stick to design-tokens: background (`bg-card`), borders (`border-border`), muted text (`text-muted-foreground`) etc.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-05-29T00:46:09.063Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Spacing utilities (`px-*`, `py-*`, `gap-*`) are preferred over custom margins.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use the `container` class with a `max-w-7xl` cap for page width consistency.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧬 Code graph analysis (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx (1)
PageHeader(7-32)apps/dashboard/src/@/components/ui/background-patterns.tsx (1)
GridPattern(32-86)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1)
mapChainIdToDexScreenerChainSlug(1-74)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1)
DexScreener(40-58)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx (1)
ContractAnalyticsOverview(10-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Size
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: Unit Tests
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (3)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (3)
81-81: Header width bump to 7xl is consistent with dashboard guidelinesLGTM.
84-100: Container max-w-7xl aligns with the layout capLGTM.
149-155: Analytics section container and growth look goodMatches the flex/grow guidance from prior layout learnings.
Merge activity
|
…ge (#8035) <!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR primarily focuses on removing the `token-price-data` API and the `PriceChart` component, while introducing a new `DexScreener` feature that displays token price information based on the chain ID and contract address. ### Detailed summary - Deleted `token-price-data.ts` and `PriceChart.tsx`. - Added `mapChainIdToDexScreenerChainSlug` to map chain IDs to DexScreener chain slugs. - Introduced `DexScreener` and `DexScreenerIframe` components for displaying token price data. - Updated `erc20.tsx` to integrate `DexScreener` and remove token price fetching logic. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added embedded DexScreener chart on ERC20 public pages for supported chains with automatic light/dark theming and responsive SSR fallback. * Introduced chain-to-DexScreener slug mapping for type-safe embeds. * **Refactor** * Removed token price data fetching and the TokenStats/price chart UI from ERC20 public pages. * **Style** * Widened layout to max-w-7xl, simplified Buy section spacing, and moved DexScreener before analytics; analytics and recent transfers now sit in a unified bottom container. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
f7230de to
c82b606
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (1)
22-26: Mark as server-only moduleThis is a server component (uses next/headers). Add the server-only marker to prevent accidental client bundling.
+import "server-only"; import { cookies } from "next/headers";
♻️ Duplicate comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)
135-147: Safer slug lookup + cleaner conditional renderAvoid
in+ index assertions; compute slug once and render conditionally.- {props.chainMetadata.chainId in mapChainIdToDexScreenerChainSlug && ( - <div className="container max-w-7xl pb-10"> - <DexScreener - chain={ - mapChainIdToDexScreenerChainSlug[ - props.chainMetadata - .chainId as keyof typeof mapChainIdToDexScreenerChainSlug - ] - } - contractAddress={props.clientContract.address} - /> - </div> - )} + {(() => { + const slug = getDexScreenerSlug(props.chainMetadata.chainId); + return slug ? ( + <div className="container max-w-7xl pb-10"> + <DexScreener + chain={slug} + contractAddress={props.clientContract.address} + /> + </div> + ) : null; + })()}
114-118: Replace inline style with Tailwind arbitrary propertyDashboard forbids inline styles; use an arbitrary property in className.
- className="text-border dark:text-border/70" - style={{ - maskImage: - "linear-gradient(to bottom right,white,transparent,transparent)", - }} + className='text-border dark:text-border/70 [mask-image:linear-gradient(to_bottom_right,white,transparent,transparent)]'
🧹 Nitpick comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)
22-26: Add explicit return types for exported and local functionsKeep TS explicit per repo guidelines.
-export async function ERC20PublicPage(props: { +export async function ERC20PublicPage(props: { serverContract: ThirdwebContract; clientContract: ThirdwebContract; chainMetadata: ChainMetadata; -}) { +}): Promise<JSX.Element> {And below in the same file:
-function BuyEmbed(props: { /* … */ }) { +function BuyEmbed(props: { /* … */ }): JSX.Element {-async function getActiveClaimConditionWithErrorHandler( +async function getActiveClaimConditionWithErrorHandler( contract: ThirdwebContract, -) { +): Promise<ActiveClaimCondition | undefined> {
15-16: Prefer a typed slug resolver over importing the map hereImport a helper (getDexScreenerSlug) and drop direct map usage to keep this module decoupled from the mapping details.
-import { DexScreener } from "./_components/dex-screener"; -import { mapChainIdToDexScreenerChainSlug } from "./_components/dex-screener-chains"; +import { DexScreener } from "./_components/dex-screener"; +import { getDexScreenerSlug } from "./_components/dex-screener-chains";Apply the usage change in Lines 135-147 (see dedicated comment).
Additional helper to add in ./_components/dex-screener-chains.ts:export function getDexScreenerSlug( chainId: number, ): DexScreenerChainSlug | undefined { return mapChainIdToDexScreenerChainSlug[ chainId as keyof typeof mapChainIdToDexScreenerChainSlug ]; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx(0 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx(3 hunks)
💤 Files with no reviewable changes (2)
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/*(Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
UseNavLinkfor internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Usecn()from@/lib/utilsfor conditional class logic
Use design system tokens (e.g.,bg-card,border-border,text-muted-foreground)
Server Components (Node edge): Start files withimport "server-only";
Client Components (browser): Begin files with'use client';
Always callgetAuthToken()to retrieve JWT from cookies on server side
UseAuthorization: Bearerheader – never embed tokens in URLs
Return typed results (e.g.,Project[],User[]) – avoidany
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stablequeryKeysfor React Query cache hits
ConfigurestaleTime/cacheTimein React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never importposthog-jsin server components
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
apps/{dashboard,playground}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/_(e.g., Button, Input, Tabs, Card)
UseNavLinkfor internal navigation to get active state handling
Use Tailwind CSS for styling; no inline styles
Merge class names withcn()from@/lib/utilsfor conditional classes
Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components must start withimport "server-only"; usenext/headers, server‑only env, heavy data fetching, andredirect()where appropriate
Client Components must start with'use client'; handle interactivity with hooks and browser APIs
Server-side data fetching: callgetAuthToken()from cookies, sendAuthorization: Bearer <token>header, and return typed results (avoidany)
Client-side data fetching: wrap calls in React Query with descriptive, stablequeryKeysand set sensiblestaleTime/cacheTime(≥ 60s default); keep tokens secret via internal routes or server actions
Do not importposthog-jsin server components (client-side only)
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Expose a
classNameprop on the root element of every component
Files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧠 Learnings (13)
📚 Learning: 2025-08-29T23:44:47.512Z
Learnt from: MananTank
PR: thirdweb-dev/js#7951
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx:38-38
Timestamp: 2025-08-29T23:44:47.512Z
Learning: The ContractPageLayout component in apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx is not the root layout - it's nested within the dashboard layout which already handles footer positioning with min-h-dvh and AppFooter placement. The ContractPageLayout needs flex flex-col grow to properly participate in the parent's flex layout.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-05-27T19:55:25.056Z
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts:49-49
Timestamp: 2025-05-27T19:55:25.056Z
Learning: In the ERC20 public pages token price data hook (`useTokenPriceData.ts`), direct array access on `json.data[0]` without optional chaining is intentionally correct and should not be changed to use safety checks.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Tailwind CSS is the styling system – avoid inline styles or CSS modules.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Never hard-code colors – always go through Tailwind variables.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Use Tailwind CSS for styling; no inline styles
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use Tailwind CSS only – no inline styles or CSS modules
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Stick to design-tokens: background (`bg-card`), borders (`border-border`), muted text (`text-muted-foreground`) etc.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-05-29T00:46:09.063Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Spacing utilities (`px-*`, `py-*`, `gap-*`) are preferred over custom margins.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use the `container` class with a `max-w-7xl` cap for page width consistency.
Applied to files:
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧬 Code graph analysis (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx (1)
PageHeader(7-32)apps/dashboard/src/@/components/ui/background-patterns.tsx (1)
GridPattern(32-86)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1)
mapChainIdToDexScreenerChainSlug(1-74)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1)
DexScreener(40-58)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx (1)
ContractAnalyticsOverview(10-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Size
- GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)
84-100: LGTM: container sizing aligned to 7xlHeader block wrapper matches dashboard width guidance.
149-155: LGTM: analytics block reflowContainerization and ordering look good; props remain typed and consistent.
| <div className="flex grow flex-col"> | ||
| <AssetPageView assetType="coin" chainId={props.chainMetadata.chainId} /> | ||
| <PageHeader containerClassName="max-w-5xl" /> | ||
| <PageHeader containerClassName="max-w-7xl" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Width cap: verify PageHeader default doesn’t override 7xl
PageHeader internally uses "container max-w-8xl" (see file snippet). Passing "max-w-7xl" here may not win the cascade. Either change PageHeader’s default to 7xl or add a specific wrapper outside PageHeader.
Run to confirm current default:
🏁 Script executed:
#!/bin/bash
rg -nC2 'export function PageHeader' apps/dashboard/src/app | sed -n '1,40p'Length of output: 788
🏁 Script executed:
#!/bin/bash
sed -n '1,240p' "apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx"Length of output: 1052
Change PageHeader default max-width to max-w-7xl
PageHeader.tsx currently sets container flex max-w-8xl ..., so passing max-w-7xl from the call site may not override Tailwind; update apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx to use max-w-7xl (or wrap PageHeader in an outer container that enforces the 7xl cap).
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx
(around the component root/container className), the component hardcodes
"max-w-8xl" which prevents callers passing containerClassName="max-w-7xl" from
taking effect; change the default class to "max-w-7xl" (or remove the hardcoded
max-w-* and merge/compose the passed containerClassName so callers can override)
so that PageHeader respects the 7xl cap from the call site.

PR-Codex overview
This PR focuses on removing the
token-price-dataAPI andPriceChartcomponent while adding a new mapping for chain IDs to DexScreener chain slugs. It introduces aDexScreenercomponent to display DexScreener information based on the selected chain and contract address.Detailed summary
token-price-data.tsandPriceChart.tsx.mapChainIdToDexScreenerChainSlugfor mapping chain IDs to DexScreener slugs.DexScreenerandDexScreenerIframecomponents for displaying DexScreener data.ERC20PublicPageto useDexScreenerbased on the chain ID.Summary by CodeRabbit
New Features
Refactor
Style