-
Notifications
You must be signed in to change notification settings - Fork 619
Dashboard: Improved chart responsiveness, code cleanup #7801
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
Dashboard: Improved chart responsiveness, code cleanup #7801
Conversation
|
WalkthroughThis update refactors analytics dashboard components to improve responsiveness, modularity, and search parameter handling. It removes legacy range selectors and suspense wrappers, introduces responsive search parameter providers and time filter components, and updates chart cards to use explicit props for selected charts. Control flow is modularized with async components and responsive suspense, and several components are renamed or replaced for clarity and maintainability. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ResponsiveTimeFilters
participant SearchParamsProvider
participant ChartCard
User->>ResponsiveTimeFilters: Selects date range or interval
ResponsiveTimeFilters->>SearchParamsProvider: Updates search params context
SearchParamsProvider->>ChartCard: Passes updated range/interval props
ChartCard->>User: Renders chart with selected filters
User->>ChartCard: Selects chart type
ChartCard->>SearchParamsProvider: Calls onSelect, updates selected chart param
SearchParamsProvider->>ChartCard: Passes new selected chart prop
ChartCard->>User: Renders updated chart
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7801 +/- ##
=======================================
Coverage 56.34% 56.34%
=======================================
Files 905 905
Lines 58806 58806
Branches 4144 4144
=======================================
Hits 33135 33135
Misses 25567 25567
Partials 104 104
🚀 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: 5
🔭 Outside diff range comments (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx (2)
275-280: Update AsyncTotalSponsoredCard to use new props patternThe
AsyncTotalSponsoredCardis still passingsearchParamstoTotalSponsoredCard, but based on the PR's pattern and other similar components, it should passselectedChartandselectedChartQueryParamprops instead.The component should be updated to match the pattern used in the team analytics page where
AsyncTotalSponsoredCardpasses explicitselectedChartandselectedChartQueryParamprops. This would require importing and usingTotalSponsoredChartCardUIfrom the shared components instead of the localTotalSponsoredCard.
436-531: Refactor TotalSponsoredCard to reuse shared TotalSponsoredChartCardUIThe in-page
TotalSponsoredCardis effectively re-implementing the logic already encapsulated byTotalSponsoredChartCardUI. Please remove the local component and switch to the shared UI primitive:• File to update
– apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx• Replace the internal
async function TotalSponsoredCard(…) { … }entirely with:import { TotalSponsoredChartCardUI } from "../(team)/_components/TotalSponsoredCard"; export default function PageWrapper({ data, aggregatedData, searchParams }) { return ( <TotalSponsoredChartCardUI data={data} aggregatedData={aggregatedData} selectedChart={searchParams?.totalSponsored as string | undefined} selectedChartQueryParam="totalSponsored" title="Gas Sponsored" description={/* optional */} onlyMainnet={/* if you only want mainnet view */} /> ); }• Key changes
- Remove all date-processing/chart logic from this file.
- Delegate state and URL param handling to
useSetResponsiveSearchParamsinside the shared component.- Pass through
data,aggregatedData,selectedChart,selectedChartQueryParam, plus any UI props you need.This aligns with the PR’s goal of consolidating chart cards and standardizing URL-driven responsiveness.
🧹 Nitpick comments (2)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemAnalyticsPage.tsx (1)
147-147: Remove redundant fallback to empty arrayThe
|| []fallback is unnecessary sinceprops.ecosystemWalletStatsis already an array (either populated or empty) based on the prop definition.- ecosystemWalletStats={props.ecosystemWalletStats || []} + ecosystemWalletStats={props.ecosystemWalletStats}Also applies to: 153-153
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx (1)
85-90: Use the defaultRange variable instead of hardcodingThe
defaultRangevariable is defined but not used in thegetFiltersFromSearchParamscall.const defaultRange: DurationId = "last-30"; const { range, interval } = getFiltersFromSearchParams({ - defaultRange: "last-30", + defaultRange, from: searchParams.from, interval: searchParams.interval, to: searchParams.to, });
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TotalSponsoredCard.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/highlights-card.tsx
Show resolved
Hide resolved
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/highlights-card.tsx
Show resolved
Hide resolved
...shboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/overview/highlights-card.tsx
Show resolved
Hide resolved
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx
Outdated
Show resolved
Hide resolved
3083496 to
ba0e1b8
Compare
ba0e1b8 to
8c4888f
Compare
5ce2058 to
5e15af1
Compare
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 focuses on enhancing the analytics components by improving the handling of date ranges, adding responsive search parameters, and refactoring several components for better performance and usability.
### Detailed summary
- Removed `range-selector.tsx` and refactored date handling.
- Updated `todayDate` calculation for timezone issues.
- Added `isPending` state to `EcosystemWalletsSummary` and other components.
- Converted several components to async functions.
- Introduced `ResponsiveTimeFilters` for better date range selection.
- Enhanced `TransactionsChartCard` and `TotalSponsoredChartCard` with chain mapping.
- Improved loading states using `ResponsiveSuspense`.
- Refactored `AppHighlightsCard` into `ProjectHighlightsCard` for better usability.
> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.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**
* Introduced responsive and modular time filter controls for analytics dashboards.
* Added new highlights cards for team and project analytics, providing aggregated metrics in a combined bar chart format.
* Added a new combined bar chart card for gas sponsorship data with dynamic chart selection.
* Added components that map transaction and sponsorship data with chain metadata for improved analytics detail.
* **Refactor**
* Replaced multiple analytics and chart components with streamlined, asynchronous, and responsive variants.
* Standardized date range and interval filtering using a centralized utility and responsive providers.
* Updated chart selection to use in-app state and callbacks instead of URL-based navigation.
* Simplified analytics page layouts by replacing Suspense with responsive suspense components.
* Externalized data processing and state management from several chart card components to improve modularity.
* Removed deprecated components and replaced them with updated responsive and async implementations.
* **Bug Fixes**
* Improved handling of date ranges and intervals, ensuring accurate and consistent filtering.
* **Chores**
* Removed unused or redundant components and consolidated stories for better maintainability.
* Cleaned up imports and type definitions across analytics and project overview pages.
* **Style**
* Enhanced button and layout styling for chart selection and analytics cards.
* **Documentation**
* Updated interactive stories for analytics components to improve clarity and usability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
5e15af1 to
5bff16b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx (1)
50-124: Clean interaction pattern with responsive search params.The switch to callback-based chart selection with
setResponsiveSearchParamsis cleaner than URL manipulation. The time series data processing could potentially be moved to the wrapper component for complete separation of concerns, but the current approach is acceptable for this lightweight processing.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
apps/dashboard/src/@/components/analytics/date-range-selector.tsx(2 hunks)apps/dashboard/src/@/components/analytics/range-selector.tsx(0 hunks)apps/dashboard/src/@/components/analytics/responsive-time-filters.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TotalSponsoredCard.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/transaction-card-with-chain-mapping.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/highlights-card.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx(9 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemAnalyticsPage.tsx(3 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/Summary.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/page.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/EngineCloudChartCard/index.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/RpcMethodBarChartCard/index.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/Transactions/TransactionCharts.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/Transactions/index.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/overview/highlights-card.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/overview/total-sponsored.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx(12 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/analytics/chart/index.tsx(4 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/page.tsx(3 hunks)apps/dashboard/src/app/(app)/team/components/Analytics/AnalyticsHeader.tsx(0 hunks)apps/dashboard/src/app/(app)/team/components/Analytics/CombinedBarChartCard.stories.tsx(3 hunks)apps/dashboard/src/app/(app)/team/components/Analytics/CombinedBarChartCard.tsx(4 hunks)
💤 Files with no reviewable changes (2)
- apps/dashboard/src/app/(app)/team/components/Analytics/AnalyticsHeader.tsx
- apps/dashboard/src/@/components/analytics/range-selector.tsx
🚧 Files skipped from review as they are similar to previous changes (19)
- apps/dashboard/src/@/components/analytics/date-range-selector.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/overview/highlights-card.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/overview/total-sponsored.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/RpcMethodBarChartCard/index.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/analytics/chart/index.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/Transactions/index.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/Summary.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/page.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/EngineCloudChartCard/index.tsx
- apps/dashboard/src/@/components/analytics/responsive-time-filters.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/Transactions/TransactionCharts.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/page.tsx
- apps/dashboard/src/app/(app)/team/components/Analytics/CombinedBarChartCard.stories.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/transaction-card-with-chain-mapping.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/highlights-card.tsx
- apps/dashboard/src/app/(app)/team/components/Analytics/CombinedBarChartCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemAnalyticsPage.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TotalSponsoredCard.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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
Files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.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)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.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)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
🧠 Learnings (26)
📓 Common learnings
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).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Surface breaking changes prominently in PR descriptions
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 : Use React Query (`tanstack/react-query`) for all client data fetching.
Learnt from: arcoraven
PR: thirdweb-dev/js#7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like `aria-label` and `role` in its TypeScript interface, causing compilation errors when added.
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/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
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 : Components that listen to user events, animations or live updates.
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 : Pages requiring fast transitions where data is prefetched on the client.
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} : Keep components pure; fetch data outside (server component or hook) and pass it down via props.
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`.
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.
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} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
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} : Local state or effects live inside; data fetching happens in hooks.
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx:29-39
Timestamp: 2025-05-27T20:10:47.245Z
Learning: MananTank prefers adding error handling (try-catch) directly inside utility functions like `shouldRenderNewPublicPage` rather than requiring callers to wrap the function calls in try-catch blocks. This centralizes error handling and benefits all callers automatically.
📚 Learning: applies to dashboard/**/*client.tsx : interactive ui that relies on hooks (`usestate`, `useeffect`, ...
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)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: the thirdwebbarchart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(side...
Learnt from: arcoraven
PR: thirdweb-dev/js#7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like `aria-label` and `role` in its TypeScript interface, causing compilation errors when added.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{ts,tsx} : export default async functions without `'use client';` – they r...
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/**/*.{ts,tsx} : Export default async functions without `'use client';` – they run on the Node edge.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*client.tsx : pages requiring fast transitions where data is prefetched on t...
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 : Pages requiring fast transitions where data is prefetched on the client.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*client.tsx : components that listen to user events, animations or live upda...
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 : Components that listen to user events, animations or live updates.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{ts,tsx} : heavy data fetching that should not ship to the client (e.g. an...
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/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/components/*.client.tsx : client components must start with `'use client';` ...
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/**/components/*.client.tsx : Client components must start with `'use client';` before imports.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : keep components pure; fetch data outside (server component or ...
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} : Keep components pure; fetch data outside (server component or hook) and pass it down via props.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: in the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractad...
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)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*client.tsx : anything that consumes hooks from `@tanstack/react-query` or t...
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 : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: the `fetchdashboardcontractmetadata` function from "@3rdweb-sdk/react/hooks/usedashboardcontractmeta...
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx:15-17
Timestamp: 2025-05-27T19:54:55.885Z
Learning: The `fetchDashboardContractMetadata` function from "3rdweb-sdk/react/hooks/useDashboardContractMetadata" has internal error handlers for all promises and cannot throw errors, so external error handling is not needed when calling this function.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsxapps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: the thirdweb project has an eslint rule that restricts direct usage of `definechain`. when it's nece...
Learnt from: MananTank
PR: thirdweb-dev/js#7298
File: apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx:424-424
Timestamp: 2025-06-06T23:46:08.795Z
Learning: The thirdweb project has an ESLint rule that restricts direct usage of `defineChain`. When it's necessary to use `defineChain` directly, it's acceptable to disable the rule with `// eslint-disable-next-line no-restricted-syntax`.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx
📚 Learning: applies to dashboard/**/*client.tsx : use react query (`@tanstack/react-query`) for all client data ...
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 : Use React Query (`tanstack/react-query`) for all client data fetching.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx
📚 Learning: applies to dashboard/**/*client.tsx : keep `querykey` stable and descriptive for cache hits....
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 : Keep `queryKey` stable and descriptive for cache hits.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx
📚 Learning: in next.js server components, the `params` object can sometimes be a promise that needs to be awaite...
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.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : for notices & skeletons rely on `announcementbanner`, `generic...
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} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to src/@/analytics/report.ts : review `src/@/analytics/report.ts` before adding analytics ev...
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to src/@/analytics/report.ts : Review `src/@/analytics/report.ts` before adding analytics events to check for duplicates
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/layout.tsx : building layout shells (`layout.tsx`) and top-level pages that ...
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/**/layout.tsx : Building layout shells (`layout.tsx`) and top-level pages that mainly assemble data.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : wrap client-side data fetching calls in r...
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} : Wrap client-side data fetching calls in React Query (`tanstack/react-query`)
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{ts,tsx} : redirect logic using `redirect()` from `next/navigation`....
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/**/*.{ts,tsx} : Redirect logic using `redirect()` from `next/navigation`.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : local state or effects live inside; data fetching happens in h...
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} : Local state or effects live inside; data fetching happens in hooks.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : reuse core ui primitives; avoid re-implementing buttons, cards...
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)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : import ui primitives from `@/components/u...
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} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*client.tsx : when you need access to browser apis (localstorage, window, in...
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 : When you need access to browser APIs (localStorage, window, IntersectionObserver etc.).
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : accept a typed `props` object and export a named function (`ex...
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} : Accept a typed `props` object and export a named function (`export function MyComponent()`).
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
🧬 Code Graph Analysis (1)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx (1)
apps/dashboard/src/@/types/analytics.ts (1)
TransactionStats(35-40)
⏰ 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, esbuild)
- GitHub Check: Build Packages
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (9)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx (3)
1-9: LGTM! Client component conversion is appropriate.The addition of
"use client"and responsive search params hook aligns with the refactor to make chart components interactive while maintaining server-side data fetching in wrapper components.
10-24: Good refactor moving chartConfig to module scope.Moving the configuration object outside the component prevents unnecessary recreations on re-renders and improves performance.
25-49: Excellent separation of concerns with explicit props.The refactor from async function with
searchParamsto sync component with explicit props improves maintainability and testability. The externalization of data processing to wrapper components follows React best practices.apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx (6)
1-45: LGTM! Import changes support the responsive architecture.The addition of responsive components and utilities aligns with the dashboard refactor goals. The SearchParams type properly defines all query parameters used by the analytics components.
47-69: Good centralization of filter processing.Using
getFiltersFromSearchParamswith a consistent default range improves maintainability across analytics pages. The Promise.all pattern for awaiting params is efficient.
70-86: Clean layout refactor with responsive provider.The ResponsiveSearchParamsProvider wrapper and simplified header structure improve maintainability. The ResponsiveTimeFilters component centralizes time filtering UI consistently.
87-167: Excellent use of ResponsiveSuspense for performance optimization.The granular
searchParamsUsedarrays enable selective re-rendering when only relevant parameters change, improving performance. The explicit prop pattern for chart selection is more maintainable than passing raw search parameters.
170-296: Well-structured async components with proper error handling.The async components properly use
Promise.allSettledfor error handling and consistently returnEmptyStateCardwhen no data is available. The explicit prop pattern for chart selection is maintained across all components.
379-423: Good async wrapper implementation following established patterns.The component properly fetches chain metadata and processes aggregated data. The
eslint-disable-next-line no-restricted-syntaxfordefineChainusage is acceptable here as this is a legitimate use case for chain metadata fetching.
<!--
## 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 focuses on enhancing analytics components by introducing responsive time filters, updating chart components to support new props, and refactoring existing code for improved clarity and functionality.
### Detailed summary
- Removed `range-selector.tsx` and refactored `AnalyticsHeader.tsx`.
- Added `ResponsiveTimeFilters` for better time range handling.
- Updated `EcosystemWalletsSummary` and `EcosystemAnalyticsPage` to use new props.
- Refactored various chart components to accept `selectedChart` and `selectedChartQueryParam`.
- Enhanced `AsyncTransactionsChartCard` and `AsyncTotalSponsoredCard` for better data handling.
- Replaced `LoadingChartState` with responsive loading states across components.
- Consolidated logic for handling time series data in analytics cards.
- Improved type definitions for better clarity and consistency.
> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.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**
* Introduced responsive and modular time filter controls for analytics dashboards.
* Added new highlights cards for team and project analytics, providing aggregated metrics in a combined bar chart format.
* Added a new combined bar chart card for gas sponsorship data with dynamic chart selection.
* Added components that map transaction and sponsorship data with chain metadata for improved analytics detail.
* **Refactor**
* Replaced multiple analytics and chart components with streamlined, asynchronous, and responsive variants.
* Standardized date range and interval filtering using a centralized utility and responsive providers.
* Updated chart selection to use in-app state and callbacks instead of URL-based navigation.
* Simplified analytics page layouts by replacing Suspense with responsive suspense components.
* Externalized data processing and state management from several chart card components to improve modularity.
* Removed deprecated components and replaced them with updated responsive and async implementations.
* **Bug Fixes**
* Improved handling of date ranges and intervals, ensuring accurate and consistent filtering.
* **Chores**
* Removed unused or redundant components and consolidated stories for better maintainability.
* Cleaned up imports and type definitions across analytics and project overview pages.
* **Style**
* Enhanced button and layout styling for chart selection and analytics cards.
* **Documentation**
* Updated interactive stories for analytics components to improve clarity and usability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
5bff16b to
bab4ff5
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
🧹 Nitpick comments (1)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx (1)
397-412: Data aggregation logic is correct but could be more readable.The mainnet/testnet classification and aggregation logic is functionally correct, but the nested filter operations could benefit from better readability.
Consider extracting the classification logic for better readability:
+ const isMainnet = (chainId: string) => + !chains.find((c) => c.chainId === Number(chainId))?.testnet; + const processedAggregatedData = { - mainnet: props.aggregatedData - .filter( - (d) => !chains.find((c) => c.chainId === Number(d.chainId))?.testnet, - ) - .reduce((acc, curr) => acc + curr.sponsoredUsd, 0), - testnet: props.aggregatedData - .filter( - (d) => chains.find((c) => c.chainId === Number(d.chainId))?.testnet, - ) - .reduce((acc, curr) => acc + curr.sponsoredUsd, 0), + mainnet: props.aggregatedData + .filter((d) => d.chainId && isMainnet(d.chainId)) + .reduce((acc, curr) => acc + curr.sponsoredUsd, 0), + testnet: props.aggregatedData + .filter((d) => d.chainId && !isMainnet(d.chainId)) + .reduce((acc, curr) => acc + curr.sponsoredUsd, 0),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
apps/dashboard/src/@/components/analytics/date-range-selector.tsx(2 hunks)apps/dashboard/src/@/components/analytics/range-selector.tsx(0 hunks)apps/dashboard/src/@/components/analytics/responsive-time-filters.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TotalSponsoredCard.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/transaction-card-with-chain-mapping.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/highlights-card.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx(9 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemAnalyticsPage.tsx(3 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/Summary.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/page.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/EngineCloudChartCard/index.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/RpcMethodBarChartCard/index.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/Transactions/TransactionCharts.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/Transactions/index.tsx(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/overview/highlights-card.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/overview/total-sponsored.tsx(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx(12 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/analytics/chart/index.tsx(4 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/page.tsx(3 hunks)apps/dashboard/src/app/(app)/team/components/Analytics/AnalyticsHeader.tsx(0 hunks)apps/dashboard/src/app/(app)/team/components/Analytics/CombinedBarChartCard.stories.tsx(3 hunks)apps/dashboard/src/app/(app)/team/components/Analytics/CombinedBarChartCard.tsx(4 hunks)
💤 Files with no reviewable changes (2)
- apps/dashboard/src/app/(app)/team/components/Analytics/AnalyticsHeader.tsx
- apps/dashboard/src/@/components/analytics/range-selector.tsx
🚧 Files skipped from review as they are similar to previous changes (20)
- apps/dashboard/src/@/components/analytics/date-range-selector.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/Summary.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/Transactions/index.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/overview/highlights-card.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/transaction-card-with-chain-mapping.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/page.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/highlights-card.tsx
- apps/dashboard/src/app/(app)/team/components/Analytics/CombinedBarChartCard.stories.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/overview/total-sponsored.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/page.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/analytics/chart/index.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemAnalyticsPage.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TransactionsCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/TotalSponsoredCard.tsx
- apps/dashboard/src/@/components/analytics/responsive-time-filters.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/EngineCloudChartCard/index.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/RpcMethodBarChartCard/index.tsx
- apps/dashboard/src/app/(app)/team/components/Analytics/CombinedBarChartCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/Transactions/TransactionCharts.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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
Files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.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)/team/[team_slug]/(team)/~/analytics/page.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)/team/[team_slug]/(team)/~/analytics/page.tsx
🧠 Learnings (23)
📓 Common learnings
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).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Surface breaking changes prominently in PR descriptions
Learnt from: arcoraven
PR: thirdweb-dev/js#7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like `aria-label` and `role` in its TypeScript interface, causing compilation errors when added.
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 : Use React Query (`tanstack/react-query`) for all client data fetching.
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/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
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 : Components that listen to user events, animations or live updates.
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 : Pages requiring fast transitions where data is prefetched on the client.
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} : Keep components pure; fetch data outside (server component or hook) and pass it down via props.
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`.
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.
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} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
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} : Local state or effects live inside; data fetching happens in hooks.
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx:29-39
Timestamp: 2025-05-27T20:10:47.245Z
Learning: MananTank prefers adding error handling (try-catch) directly inside utility functions like `shouldRenderNewPublicPage` rather than requiring callers to wrap the function calls in try-catch blocks. This centralizes error handling and benefits all callers automatically.
📚 Learning: applies to dashboard/**/*client.tsx : pages requiring fast transitions where data is prefetched on t...
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 : Pages requiring fast transitions where data is prefetched on the client.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: in next.js server components, the `params` object can sometimes be a promise that needs to be awaite...
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.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{ts,tsx} : heavy data fetching that should not ship to the client (e.g. an...
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/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*client.tsx : interactive ui that relies on hooks (`usestate`, `useeffect`, ...
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)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : for notices & skeletons rely on `announcementbanner`, `generic...
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} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to src/@/analytics/report.ts : review `src/@/analytics/report.ts` before adding analytics ev...
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to src/@/analytics/report.ts : Review `src/@/analytics/report.ts` before adding analytics events to check for duplicates
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: the thirdwebbarchart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(side...
Learnt from: arcoraven
PR: thirdweb-dev/js#7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like `aria-label` and `role` in its TypeScript interface, causing compilation errors when added.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*client.tsx : components that listen to user events, animations or live upda...
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 : Components that listen to user events, animations or live updates.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : wrap client-side data fetching calls in r...
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} : Wrap client-side data fetching calls in React Query (`tanstack/react-query`)
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/layout.tsx : building layout shells (`layout.tsx`) and top-level pages that ...
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/**/layout.tsx : Building layout shells (`layout.tsx`) and top-level pages that mainly assemble data.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*client.tsx : anything that consumes hooks from `@tanstack/react-query` or t...
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 : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{ts,tsx} : redirect logic using `redirect()` from `next/navigation`....
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/**/*.{ts,tsx} : Redirect logic using `redirect()` from `next/navigation`.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : local state or effects live inside; data fetching happens in h...
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} : Local state or effects live inside; data fetching happens in hooks.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : reuse core ui primitives; avoid re-implementing buttons, cards...
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)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : import ui primitives from `@/components/u...
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} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*client.tsx : when you need access to browser apis (localstorage, window, in...
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 : When you need access to browser APIs (localStorage, window, IntersectionObserver etc.).
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : keep components pure; fetch data outside (server component or ...
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} : Keep components pure; fetch data outside (server component or hook) and pass it down via props.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: in the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractad...
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)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : prefer composable primitives over custom markup: `button`, `in...
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)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{tsx,jsx} : accept a typed `props` object and export a named function (`ex...
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} : Accept a typed `props` object and export a named function (`export function MyComponent()`).
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: applies to dashboard/**/*.{ts,tsx} : export default async functions without `'use client';` – they r...
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/**/*.{ts,tsx} : Export default async functions without `'use client';` – they run on the Node edge.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
📚 Learning: the `fetchdashboardcontractmetadata` function from "@3rdweb-sdk/react/hooks/usedashboardcontractmeta...
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx:15-17
Timestamp: 2025-05-27T19:54:55.885Z
Learning: The `fetchDashboardContractMetadata` function from "3rdweb-sdk/react/hooks/useDashboardContractMetadata" has internal error handlers for all promises and cannot throw errors, so external error handling is not needed when calling this function.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
⏰ 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, esbuild)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Build Packages
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (7)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx (7)
1-25: LGTM! Clean refactoring to responsive components.The import changes properly introduce the responsive search parameters provider and suspense components, along with the new responsive time filters. The addition of chain metadata utilities aligns with the enhanced chain processing functionality.
62-68: LGTM! Centralized filter parsing improves maintainability.The use of
getFiltersFromSearchParamswith a default range centralizes date range parsing logic, which is a good practice for consistency across analytics pages.
71-85: Excellent responsive provider pattern implementation.The page structure properly wraps content in
ResponsiveSearchParamsProviderand replaces the previous analytics header with a clean static title and responsive time filters. This follows the established pattern from the broader refactoring effort.
89-104: Well-structured responsive suspense with proper dependencies.The ResponsiveSuspense correctly specifies search parameters it depends on, and the AsyncTeamHighlightsCard properly receives explicit chart selection props instead of raw search parameters. This improves modularity and makes dependencies explicit.
170-214: Component rename and prop structure improvements look good.The component rename from
AsyncAppHighlightsCardtoAsyncTeamHighlightsCardbetter reflects its purpose, and the new prop structure with explicitselectedChartandselectedChartQueryParamis cleaner than passing raw search parameters.
36-45: Search parameter names verified as consistent across analytics components.All three new keys—
appHighlights,client_transactions, anduserOpUsage—are defined inSearchParamsand used identically in every analytics page (selectedChartQueryParam, searchParamsUsed, and type checks). No mismatches found; no further changes needed.
258-296: ✅ TransactionsChartCardWithChainMapping component verified
- The component exists and its props (
data,aggregatedData,selectedChart,selectedChartQueryParam, etc.) align with how it’s invoked inAsyncTransactionsChartCard.- It correctly fetches and filters chain metadata (with error handling), computes
processedAggregatedData, and passes all required data toTransactionsChartCardUI.No further changes needed.
| async function AsyncTotalSponsoredChartCard(props: { | ||
| data: UserOpStats[]; | ||
| aggregatedData: UserOpStats[]; | ||
| selectedChart: string | undefined; | ||
| className?: string; | ||
| onlyMainnet?: boolean; | ||
| title?: string; | ||
| selectedChartQueryParam: string; | ||
| description?: string; | ||
| }) { | ||
| const chains = await Promise.all( | ||
| props.data.map( | ||
| (item) => | ||
| // eslint-disable-next-line no-restricted-syntax | ||
| item.chainId && getChainMetadata(defineChain(Number(item.chainId))), | ||
| ), | ||
| ).then((chains) => chains.filter((c) => c) as ChainMetadata[]); | ||
|
|
||
| const processedAggregatedData = { | ||
| mainnet: props.aggregatedData | ||
| .filter( | ||
| (d) => !chains.find((c) => c.chainId === Number(d.chainId))?.testnet, | ||
| ) | ||
| .reduce((acc, curr) => acc + curr.sponsoredUsd, 0), | ||
| testnet: props.aggregatedData | ||
| .filter( | ||
| (d) => chains.find((c) => c.chainId === Number(d.chainId))?.testnet, | ||
| ) | ||
| .reduce((acc, curr) => acc + curr.sponsoredUsd, 0), | ||
| total: props.aggregatedData.reduce( | ||
| (acc, curr) => acc + curr.sponsoredUsd, | ||
| 0, | ||
| ), | ||
| }; | ||
|
|
||
| return ( | ||
| <TotalSponsoredChartCardUI | ||
| chains={chains} | ||
| processedAggregatedData={processedAggregatedData} | ||
| selectedChart={props.selectedChart} | ||
| selectedChartQueryParam={props.selectedChartQueryParam} | ||
| data={props.data} | ||
| /> | ||
| ); | ||
| } |
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.
🛠️ Refactor suggestion
Chain metadata processing logic needs optimization.
The new AsyncTotalSponsoredChartCard function has a performance concern: it calls getChainMetadata for every data item, which could result in redundant API calls for the same chain IDs.
Consider optimizing the chain metadata fetching:
- const chains = await Promise.all(
- props.data.map(
- (item) =>
- // eslint-disable-next-line no-restricted-syntax
- item.chainId && getChainMetadata(defineChain(Number(item.chainId))),
- ),
- ).then((chains) => chains.filter((c) => c) as ChainMetadata[]);
+ // Get unique chain IDs to avoid duplicate API calls
+ const uniqueChainIds = [...new Set(props.data.map(item => item.chainId).filter(Boolean))];
+ const chains = await Promise.all(
+ uniqueChainIds.map(
+ (chainId) =>
+ getChainMetadata(defineChain(Number(chainId))),
+ ),
+ ).then((chains) => chains.filter((c) => c) as ChainMetadata[]);📝 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.
| async function AsyncTotalSponsoredChartCard(props: { | |
| data: UserOpStats[]; | |
| aggregatedData: UserOpStats[]; | |
| selectedChart: string | undefined; | |
| className?: string; | |
| onlyMainnet?: boolean; | |
| title?: string; | |
| selectedChartQueryParam: string; | |
| description?: string; | |
| }) { | |
| const chains = await Promise.all( | |
| props.data.map( | |
| (item) => | |
| // eslint-disable-next-line no-restricted-syntax | |
| item.chainId && getChainMetadata(defineChain(Number(item.chainId))), | |
| ), | |
| ).then((chains) => chains.filter((c) => c) as ChainMetadata[]); | |
| const processedAggregatedData = { | |
| mainnet: props.aggregatedData | |
| .filter( | |
| (d) => !chains.find((c) => c.chainId === Number(d.chainId))?.testnet, | |
| ) | |
| .reduce((acc, curr) => acc + curr.sponsoredUsd, 0), | |
| testnet: props.aggregatedData | |
| .filter( | |
| (d) => chains.find((c) => c.chainId === Number(d.chainId))?.testnet, | |
| ) | |
| .reduce((acc, curr) => acc + curr.sponsoredUsd, 0), | |
| total: props.aggregatedData.reduce( | |
| (acc, curr) => acc + curr.sponsoredUsd, | |
| 0, | |
| ), | |
| }; | |
| return ( | |
| <TotalSponsoredChartCardUI | |
| chains={chains} | |
| processedAggregatedData={processedAggregatedData} | |
| selectedChart={props.selectedChart} | |
| selectedChartQueryParam={props.selectedChartQueryParam} | |
| data={props.data} | |
| /> | |
| ); | |
| } | |
| async function AsyncTotalSponsoredChartCard(props: { | |
| data: UserOpStats[]; | |
| aggregatedData: UserOpStats[]; | |
| selectedChart: string | undefined; | |
| className?: string; | |
| onlyMainnet?: boolean; | |
| title?: string; | |
| selectedChartQueryParam: string; | |
| description?: string; | |
| }) { | |
| // Get unique chain IDs to avoid duplicate API calls | |
| const uniqueChainIds = [...new Set(props.data.map(item => item.chainId).filter(Boolean))]; | |
| const chains = await Promise.all( | |
| uniqueChainIds.map( | |
| (chainId) => | |
| getChainMetadata(defineChain(Number(chainId))), | |
| ), | |
| ).then((chains) => chains.filter((c) => c) as ChainMetadata[]); | |
| const processedAggregatedData = { | |
| mainnet: props.aggregatedData | |
| .filter( | |
| (d) => !chains.find((c) => c.chainId === Number(d.chainId))?.testnet, | |
| ) | |
| .reduce((acc, curr) => acc + curr.sponsoredUsd, 0), | |
| testnet: props.aggregatedData | |
| .filter( | |
| (d) => chains.find((c) => c.chainId === Number(d.chainId))?.testnet, | |
| ) | |
| .reduce((acc, curr) => acc + curr.sponsoredUsd, 0), | |
| total: props.aggregatedData.reduce( | |
| (acc, curr) => acc + curr.sponsoredUsd, | |
| 0, | |
| ), | |
| }; | |
| return ( | |
| <TotalSponsoredChartCardUI | |
| chains={chains} | |
| processedAggregatedData={processedAggregatedData} | |
| selectedChart={props.selectedChart} | |
| selectedChartQueryParam={props.selectedChartQueryParam} | |
| data={props.data} | |
| /> | |
| ); | |
| } |
🤖 Prompt for AI Agents
In apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/analytics/page.tsx
between lines 379 and 423, the function AsyncTotalSponsoredChartCard calls
getChainMetadata for every item in props.data, causing redundant calls for
duplicate chain IDs. To fix this, first extract unique chain IDs from
props.data, then call getChainMetadata only once per unique chain ID. Replace
the current Promise.all mapping with a process that fetches metadata for these
unique chain IDs, improving performance by avoiding repeated API calls.

PR-Codex overview
This PR focuses on enhancing analytics components by introducing responsive time filters, improving data handling, and refactoring various chart components for better performance and usability.
Detailed summary
range-selector.tsxand updated date handling indate-range-selector.tsx.ResponsiveTimeFilterscomponent for responsive date range selection.TransactionsChartCard,TotalSponsoredChartCard, and others to include new parameters.AsyncEcosystemWalletUsersAnalyticsfor better data management.ResponsiveSuspensefor improved user experience.AppHighlightsCardtoProjectHighlightsCardfor better context in analytics.Summary by CodeRabbit
New Features
Refactor
Bug Fixes
Chores
Style
Documentation