-
Notifications
You must be signed in to change notification settings - Fork 547
[Dashboard] Add detailed usage breakdown and billing preview #7290
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] Add detailed usage breakdown and billing preview #7290
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
WalkthroughThe changes introduce a new billing preview API module and a React component for displaying usage category details. Several files related to usage analytics and RPC usage fetching are removed. The team usage page is refactored to use the new billing preview data, with a simplified control flow and updated UI components for usage breakdown and summary. Minor UI enhancements and prop signature updates are also made in the billing settings and layout components. Additionally, multiple files replace Changes
Sequence Diagram(s)sequenceDiagram
participant Page
participant BillingPreviewAPI
participant PlanInfoCard
participant UsageCategoryDetails
Page->>BillingPreviewAPI: getBilledUsage(teamSlug)
BillingPreviewAPI-->>Page: UsageApiResponse (usage categories)
Page->>PlanInfoCard: Fetch team subscriptions
Page->>UsageCategoryDetails: For each UsageCategory in UsageApiResponse
UsageCategoryDetails-->>Page: Render category details
sequenceDiagram
participant PlanInfoCard
participant BillingInfo
participant SubscriptionOverview
PlanInfoCard->>BillingInfo: Pass teamSlug and subscriptions
BillingInfo->>SubscriptionOverview: Pass subscription and title (string or React node)
SubscriptionOverview-->>BillingInfo: Render title (conditional on type)
sequenceDiagram
participant AccountAbstractionPage as AccountAbstractionPage
participant TeamDataAPI as TeamDataAPI
participant Auth as Auth
participant SubscriptionsAPI as SubscriptionsAPI
participant ProjectsAPI as ProjectsAPI
participant ThirdwebClient as ThirdwebClient
participant SponsoredTransactionsTable as SponsoredTransactionsTable
AccountAbstractionPage->>TeamDataAPI: fetch team by slug
AccountAbstractionPage->>Auth: get auth token
alt Not authenticated
Auth-->>AccountAbstractionPage: redirect to login
else Team not found
TeamDataAPI-->>AccountAbstractionPage: redirect to /team
else
AccountAbstractionPage->>SubscriptionsAPI: fetch team subscriptions
AccountAbstractionPage->>ProjectsAPI: fetch team projects
alt No usage subscription
AccountAbstractionPage-->>User: render upgrade prompt
else
AccountAbstractionPage->>ThirdwebClient: initialize with JWT and team ID
AccountAbstractionPage->>SponsoredTransactionsTable: render with props
end
end
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #7290 +/- ##
=======================================
Coverage 55.58% 55.58%
=======================================
Files 909 909
Lines 58670 58670
Branches 4158 4158
=======================================
Hits 32609 32609
Misses 25954 25954
Partials 107 107
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (1)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/layout.tsx (1)
5-11
: 🛠️ Refactor suggestion
params
should not be typed as aPromise
in a Next-app Router layout
params
is synchronously provided by the framework; declaring it asPromise
forces an unneededawait
, hurts type-safety, and can break IDE IntelliSense.-export default async function Layout(props: { - children: React.ReactNode; - params: Promise<{ - team_slug: string; - }>; -}) { - const params = await props.params; +export default function Layout(props: { + children: React.ReactNode; + params: { + team_slug: string; + }; +}) { + const params = props.params;
🧹 Nitpick comments (4)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/layout.tsx (1)
15-30
: Minor accessibility & semantics tweak for the action buttons
UsingButton
withasChild
keeps visual styling but the final element is still an<a>
. Consider addingaria-label
(or descriptive link text) so screen-reader users can understand the destinations without needing surrounding context.apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/billing/components/PlanInfoCard.tsx (1)
299-309
: Ensure the composite “Usage” title remains semantically correct
h5
is rendered conditionally inside a flex container that already sits in anh5
context when the prop is a string. Wrapping a link inside the heading avoids duplicate heading levels and improves semantics:-<div className="flex items-center"> - <h5 className="mr-1 font-medium text-base">Usage</h5>{" "} - <span className="text-muted-foreground text-sm"> - -{" "} - <Link - className="hover:underline" - href={`/team/${teamSlug}/~/usage`} - > - View Breakdown - </Link> - </span> -</div> +<h5 className="font-medium text-base"> + Usage{" "} + <span className="text-muted-foreground text-sm"> + –{" "} + <Link className="hover:underline" href={`/team/${teamSlug}/~/usage`}> + View Breakdown + </Link> + </span> +</h5>apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx (1)
50-71
: Repeated “Something went wrong” blocks indicate copy-paste; extract helper or compress logic
You can guard once and render a common error component to keep the page concise.apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/usage-category-details.tsx (1)
63-65
: Consider improving the key generation strategy.Using
${item.description}_${index}
for React keys could cause issues if descriptions are not unique, as the same description would generate duplicate keys.Consider using a more robust key if available:
- key={`${item.description}_${index}`} + key={item.id || `${item.description}_${index}`}Or if there's no unique identifier, consider using a hash of the item properties.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
apps/dashboard/src/@/api/usage/billing-preview.ts
(1 hunks)apps/dashboard/src/@/api/usage/rpc.ts
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/usage-category-details.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/billing/components/PlanInfoCard.tsx
(4 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/layout.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/UsageCard.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx
(2 hunks)
💤 Files with no reviewable changes (3)
- apps/dashboard/src/@/api/usage/rpc.ts
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/UsageCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/billing/components/PlanInfoCard.tsx (1)
apps/dashboard/src/@/api/team-subscription.ts (1)
TeamSubscription
(23-40)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: Size
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Lint Packages
- GitHub Check: Unit Tests
- GitHub Check: Build Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (7)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx (1)
23-31
: 🛠️ Refactor suggestion
params
is declared asPromise
but supplied synchronously by Next.js
Same issue as inlayout.tsx
, remove thePromise
and theawait
.⛔ Skipped due to learnings
Learnt from: MananTank PR: thirdweb-dev/js#7152 File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx:2-10 Timestamp: 2025-05-26T16:28:10.079Z Learning: In Next.js 14+, the `params` object in page components is always a Promise that needs to be awaited, so the correct typing is `params: Promise<ParamsType>` rather than `params: ParamsType`.
Learnt from: jnsdls PR: thirdweb-dev/js#6929 File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19 Timestamp: 2025-05-21T05:17:31.283Z Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/usage-category-details.tsx (6)
1-21
: LGTM! Clean imports and interface definition.The imports are well-organized and the interface is appropriately typed.
24-27
: LGTM! Correct total calculation.The reduce operation correctly sums the
amountUsdCents
from all line items.
75-78
: LGTM! Appropriate formatPrice usage.The formatPrice calls correctly use
isUnitPrice: true
for unit prices (allowing higher precision) and standard formatting for amounts.Also applies to: 81-81
109-130
: LGTM! Well-implemented currency formatting function.The formatPrice function handles edge cases properly:
- Converts string inputs to numbers
- Returns "N/A" for invalid values
- Correctly converts cents to dollars
- Uses appropriate precision for unit prices vs. regular amounts
- Follows standard currency formatting conventions
86-94
: LGTM! Appropriate placeholder for empty state.The "No usage during this period" message properly handles the case when all line items are filtered out.
98-104
: LGTM! Conditional subtotal display.The subtotal is appropriately shown only when there are actual charges, improving the UI clarity.
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/usage-category-details.tsx
Outdated
Show resolved
Hide resolved
size-limit report 📦
|
4027a3f
to
a5ad05d
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: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (38)
apps/dashboard/src/@/api/usage/billing-preview.ts
(1 hunks)apps/dashboard/src/@/api/usage/rpc.ts
(0 hunks)apps/dashboard/src/@/components/blocks/charts/area-chart.tsx
(2 hunks)apps/dashboard/src/@/components/blocks/charts/bar-chart.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/components/account-signer.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/ContractAnalyticsPage.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/opengraph-image.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/opengraph-image.tsx
(1 hunks)apps/dashboard/src/app/(app)/account/wallets/LinkWalletUI.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/usage-category-details.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/projects/TeamProjectsPage.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/billing/components/PlanInfoCard.tsx
(5 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/members/ManageInvitesSection.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/layout.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/UsageCard.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/rpc/components/count-graph.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/rpc/components/rate-graph.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/storage/your-files.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/EngineCloudChartCard/EngineCloudBarChartCardUI.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/RpcMethodBarChartCard/RpcMethodBarChartCardUI.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-table/tx-table-ui.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/wallet-table-ui.client.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/alerts/components/ManageEngineAlerts.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/transactions-table.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx
(2 hunks)apps/dashboard/src/components/contract-components/published-contract/index.tsx
(1 hunks)apps/dashboard/src/components/embedded-wallets/Analytics/InAppWalletUsersChartCard.tsx
(2 hunks)apps/dashboard/src/components/embedded-wallets/Users/index.tsx
(1 hunks)apps/dashboard/src/components/settings/AuthorizedWallets/AuthorizedWalletsTable.tsx
(1 hunks)apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/SponsoredTransactionsChartCard.tsx
(2 hunks)apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/TotalSponsoredChartCard.tsx
(2 hunks)apps/dashboard/src/utils/date-utils.ts
(1 hunks)
💤 Files with no reviewable changes (3)
- apps/dashboard/src/@/api/usage/rpc.ts
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/UsageCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx
✅ Files skipped from review due to trivial changes (28)
- apps/dashboard/src/components/contract-components/published-contract/index.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/storage/your-files.tsx
- apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/opengraph-image.tsx
- apps/dashboard/src/components/embedded-wallets/Users/index.tsx
- apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/opengraph-image.tsx
- apps/dashboard/src/@/components/blocks/charts/bar-chart.tsx
- apps/dashboard/src/components/settings/AuthorizedWallets/AuthorizedWalletsTable.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx
- apps/dashboard/src/utils/date-utils.ts
- apps/dashboard/src/components/embedded-wallets/Analytics/InAppWalletUsersChartCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-table/tx-table-ui.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/alerts/components/ManageEngineAlerts.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx
- apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/SponsoredTransactionsChartCard.tsx
- apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/TotalSponsoredChartCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/members/ManageInvitesSection.tsx
- apps/dashboard/src/@/components/blocks/charts/area-chart.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/rpc/components/rate-graph.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/wallet-table-ui.client.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/RpcMethodBarChartCard/RpcMethodBarChartCardUI.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/transactions-table.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/EngineCloudChartCard/EngineCloudBarChartCardUI.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/components/account-signer.tsx
- apps/dashboard/src/app/(app)/account/wallets/LinkWalletUI.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/usage-category-details.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/layout.tsx
- apps/dashboard/src/@/api/usage/billing-preview.ts
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/billing/components/PlanInfoCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: Unit Tests
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Size
- GitHub Check: Build Packages
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
...p/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/ContractAnalyticsPage.tsx
Show resolved
Hide resolved
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/rpc/components/count-graph.tsx
Show resolved
Hide resolved
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/projects/TeamProjectsPage.tsx
Show resolved
Hide resolved
a5ad05d
to
0c782cc
Compare
0c782cc
to
9e051ff
Compare
9e051ff
to
497a570
Compare
497a570
to
aec443c
Compare
aec443c
to
f7fde11
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: 2
🧹 Nitpick comments (1)
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/account-abstraction/page.tsx (1)
4-6
: Consider using absolute imports for better maintainability.The relative imports with multiple
../
segments reduce readability and make refactoring more difficult.Consider updating the import paths to use absolute imports if configured in your TypeScript/bundler setup:
-import { getProjects } from "../../../../../../../../@/api/projects"; -import { getTeamSubscriptions } from "../../../../../../../../@/api/team-subscription"; -import { getAuthToken } from "../../../../../../api/lib/getAuthToken"; +import { getProjects } from "@/api/projects"; +import { getTeamSubscriptions } from "@/api/team-subscription"; +import { getAuthToken } from "@/api/lib/getAuthToken";
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (40)
apps/dashboard/src/@/api/usage/billing-preview.ts
(1 hunks)apps/dashboard/src/@/api/usage/rpc.ts
(0 hunks)apps/dashboard/src/@/components/blocks/charts/area-chart.tsx
(2 hunks)apps/dashboard/src/@/components/blocks/charts/bar-chart.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/components/account-signer.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/ContractAnalyticsPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
(2 hunks)apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/opengraph-image.tsx
(1 hunks)apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/opengraph-image.tsx
(1 hunks)apps/dashboard/src/app/(app)/account/wallets/LinkWalletUI.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/usage-category-details.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/projects/TeamProjectsPage.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/billing/components/PlanInfoCard.tsx
(5 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/members/ManageInvitesSection.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/account-abstraction/page.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/layout.tsx
(3 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/UsageCard.tsx
(0 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/rpc/components/count-graph.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/rpc/components/rate-graph.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/storage/your-files.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/EngineCloudChartCard/EngineCloudBarChartCardUI.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/RpcMethodBarChartCard/RpcMethodBarChartCardUI.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-table/tx-table-ui.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/wallet-table-ui.client.tsx
(1 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/alerts/components/ManageEngineAlerts.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/transactions-table.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx
(2 hunks)apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx
(1 hunks)apps/dashboard/src/components/contract-components/published-contract/index.tsx
(1 hunks)apps/dashboard/src/components/embedded-wallets/Analytics/InAppWalletUsersChartCard.tsx
(2 hunks)apps/dashboard/src/components/embedded-wallets/Users/index.tsx
(1 hunks)apps/dashboard/src/components/settings/AuthorizedWallets/AuthorizedWalletsTable.tsx
(1 hunks)apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/SponsoredTransactionsChartCard.tsx
(2 hunks)apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/TotalSponsoredChartCard.tsx
(2 hunks)apps/dashboard/src/utils/date-utils.ts
(1 hunks)
💤 Files with no reviewable changes (3)
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/UsageCard.tsx
- apps/dashboard/src/@/api/usage/rpc.ts
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx
✅ Files skipped from review due to trivial changes (10)
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/components/account-signer.tsx
- apps/dashboard/src/components/settings/AuthorizedWallets/AuthorizedWalletsTable.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/storage/your-files.tsx
- apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/opengraph-image.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/wallet-table-ui.client.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-table/tx-table-ui.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/RpcMethodBarChartCard/RpcMethodBarChartCardUI.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx
- apps/dashboard/src/@/api/usage/billing-preview.ts
🚧 Files skipped from review as they are similar to previous changes (25)
- apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/opengraph-image.tsx
- apps/dashboard/src/components/contract-components/published-contract/index.tsx
- apps/dashboard/src/components/embedded-wallets/Users/index.tsx
- apps/dashboard/src/@/components/blocks/charts/area-chart.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/rpc/components/rate-graph.tsx
- apps/dashboard/src/utils/date-utils.ts
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx
- apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/ContractAnalyticsPage.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/rpc/components/count-graph.tsx
- apps/dashboard/src/@/components/blocks/charts/bar-chart.tsx
- apps/dashboard/src/components/embedded-wallets/Analytics/InAppWalletUsersChartCard.tsx
- apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/SponsoredTransactionsChartCard.tsx
- apps/dashboard/src/app/(app)/account/wallets/LinkWalletUI.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/members/ManageInvitesSection.tsx
- apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/TotalSponsoredChartCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/layout.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/transactions-table.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/EngineCloudChartCard/EngineCloudBarChartCardUI.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/projects/TeamProjectsPage.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/usage-category-details.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/settings/billing/components/PlanInfoCard.tsx
- apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/alerts/components/ManageEngineAlerts.tsx
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: Unit Tests
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Build Packages
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Lint Packages
- GitHub Check: Size
- GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/page.tsx (1)
260-260
: LGTM! Clean refactoring to support component reusability.Exporting
AsyncTotalSponsoredCard
aligns well with the PR objectives of adding detailed usage breakdown and billing preview functionality. This enables the component to be reused in other parts of the application while maintaining the existing implementation unchanged.apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/account-abstraction/page.tsx (4)
16-19
: Good use of concurrent data fetching.Excellent use of
Promise.all
to fetch data concurrently, which improves performance by avoiding sequential API calls.Also applies to: 29-32
34-45
: Well-implemented subscription validation with clear user feedback.The subscription type checking and user-friendly error message for free plan users provides a good user experience with clear next steps.
52-64
: Clean component structure and appropriate prop passing.The component renders the
SponsoredTransactionsTable
with all necessary props including the subscription period boundaries, which ensures the usage data is scoped to the correct billing period.
21-23
:⚠️ Potential issueFix missing return statement after loginRedirect.
The
loginRedirect
call is not followed by areturn
statement, which means execution will continue even after the redirect is initiated. This could lead to unexpected behavior or runtime errors.Add a
return
statement after the redirect:if (!authToken) { loginRedirect(`/team/${params.team_slug}/~/usage/account-abstraction`); + return; }
⛔ Skipped due to learnings
Learnt from: MananTank PR: thirdweb-dev/js#7285 File: apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx:57-57 Timestamp: 2025-06-05T13:59:49.886Z Learning: In the thirdweb dashboard Next.js app, when using loginRedirect() in server components, ensure to add a return statement after the redirect call to prevent further code execution and potential security issues.
Learnt from: MananTank PR: thirdweb-dev/js#7228 File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/settings/page.tsx:23-25 Timestamp: 2025-05-30T18:14:57.074Z Learning: In the dashboard codebase, the `loginRedirect` function performs an actual page redirect that automatically stops execution, similar to Next.js `redirect()`. No return statement is needed after calling `loginRedirect` as it handles flow control internally.
Add Usage Breakdown Page for Team Billing
This PR adds a new usage breakdown page that provides detailed information about a team's current billing period usage. The implementation includes:
The PR also updates the billing info component to include a link to the new usage breakdown page, making it easier for users to understand their current charges.
Summary by CodeRabbit
New Features
Refactor
Bug Fixes
Style
Removed
PR-Codex overview
This PR primarily focuses on refactoring date formatting across various components by replacing
formatDate
withformat
fromdate-fns
. It also introduces new components for displaying usage category details and updates the layout of the usage page to include billing settings and invoice history links.Detailed summary
Usage.tsx
andUsageCard.tsx
.formatDate
withformat
in multiple components.UsageCategoryDetails
component to display usage category details.PlanInfoCardUI
to show subscription details with a link to view usage breakdown.formatPrice
helper for currency formatting.