Skip to content

feat(dashboard): add usage alerts#4082

Closed
jog1t wants to merge 1 commit intomainfrom
01-31-feat_dashboard_add_usage_alerts
Closed

feat(dashboard): add usage alerts#4082
jog1t wants to merge 1 commit intomainfrom
01-31-feat_dashboard_add_usage_alerts

Conversation

@jog1t
Copy link
Contributor

@jog1t jog1t commented Jan 31, 2026

TL;DR

Enhanced billing UI with new plan badges, usage alerts, and improved context switcher integration.

What changed?

  • Added a new BillingLimitAlert component that displays warnings when approaching or exceeding usage limits
  • Enhanced the BillingPlanBadge with new styling and support for a "Team" plan tier
  • Updated the usage gauge to show different visual indicators based on usage percentage
  • Improved the context switcher to display plan badges next to projects and sort current selections to the top
  • Updated billing plan card UI with clearer button text and styling
  • Added premium badge variants with gradient and animation effects
  • Fixed namespace list pagination by increasing the limit from the default to 100

How to test?

  1. Check the billing UI with different usage percentages to see the alerts and gauge changes
  2. Verify the new premium badge styling for Team, Pro, and Enterprise plans
  3. Open the context switcher to see plan badges next to projects
  4. Test the sorting behavior in project and namespace lists
  5. Verify that the billing limit alert appears when usage is high on the free plan

Why make this change?

These changes improve the visibility of billing information throughout the application, making it easier for users to understand their current plan and usage status. The new alerts help prevent unexpected service interruptions by proactively notifying users when they're approaching usage limits. The premium badge styling creates visual distinction between different plan tiers, and the context switcher improvements help users quickly identify which projects are on which plans.

@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4082 January 31, 2026 00:57 Destroyed
@railway-app
Copy link

railway-app bot commented Jan 31, 2026

🚅 Deployed to the rivet-pr-4082 environment in rivet-frontend

Service Status Web Updated (UTC)
frontend-cloud 😴 Sleeping (View Logs) Web Jan 31, 2026 at 1:09 am
frontend-inspector 😴 Sleeping (View Logs) Web Jan 31, 2026 at 1:06 am
website ❌ Build Failed (View Logs) Web Jan 31, 2026 at 1:00 am
mcp-hub ✅ Success (View Logs) Web Jan 31, 2026 at 12:58 am

@jog1t jog1t marked this pull request as ready for review January 31, 2026 00:57
Copy link
Contributor Author

jog1t commented Jan 31, 2026


How to use the Graphite Merge Queue

Add the label merge-queue to this PR to add it to 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.

@graphite-app
Copy link
Contributor

graphite-app bot commented Jan 31, 2026

Graphite Automations

"Test" took an action on this PR • (01/31/26)

1 assignee was added to this PR based on Kacper Wojciechowski's automation.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 31, 2026

More templates

@rivetkit/virtual-websocket

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@4082

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@4082

@rivetkit/db

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/db@4082

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@4082

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@4082

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@4082

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@4082

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@4082

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@4082

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@4082

commit: ce15f2b

@claude
Copy link

claude bot commented Jan 31, 2026

PR Review: Usage Alerts and Billing UI Enhancements

Overview

This PR adds valuable user-facing features to improve billing visibility and prevent service interruptions. The implementation is generally solid with good attention to UX details.

Code Quality ✅

Strengths

  • Clean component structure with good separation of concerns
  • Proper use of TypeScript types and React hooks
  • Consistent styling patterns using Tailwind classes
  • Good accessibility with ARIA labels on SVG elements

Issues Found

1. Double Space in className (Minor)

frontend/src/app/billing/billing-limit-alert.tsx:24

"mx-0.5 mb-2 p-2 rounded-md border  text-xs",
//                                  ^^ extra space

2. Potential Layout Issue (Minor)

frontend/src/app/billing/billing-limit-alert.tsx:38

<div className="flex-1 flex min-w-0 items-center justify-center">

Using justify-center on a flex container with items-center seems odd. The inner content uses flex-1 which would stretch anyway. Consider if justify-between was intended, or if this should be justify-start.

3. Hardcoded Limit Change (Significant)

frontend/src/app/data-providers/cloud-data-provider.tsx:111,115

The change from RECORDS_PER_PAGE (10) to hardcoded 100 is concerning:

  • Inconsistency: Other pagination in the codebase uses RECORDS_PER_PAGE
  • Magic Number: The value 100 lacks context about why this specific limit
  • Performance: Loading 100 namespaces upfront could impact performance for users with many namespaces
  • Pagination Logic: The hardcoded value appears in both the query limit and the getNextPageParam check, creating maintenance burden

Recommendation: Either:

  • Create a constant like NAMESPACE_LIST_LIMIT = 100 with a comment explaining why
  • Or better: keep using RECORDS_PER_PAGE and handle the pagination properly in the UI

The PR description mentions "Fixed namespace list pagination by increasing the limit from the default to 100" but doesn't explain why this is needed. Was there a bug? A UX issue? This needs documentation.

Performance Considerations

Potential Issues

  1. Multiple Billing Queries

    • BillingLimitAlert, BillingUsageGauge, and BillingPlanBadge each independently query billing data
    • React Query should deduplicate these, but verify caching is working correctly
    • Consider lifting billing data to a shared context if needed
  2. Namespace Loading

    • The hardcoded limit of 100 namespaces could cause slow initial loads for projects with many namespaces
    • The context switcher now loads all 100 upfront instead of paginating with 10 at a time
    • Consider lazy loading or virtualization for the list
  3. Sort Operation on Every Render
    frontend/src/app/context-switcher.tsx:308-315,500-507

    • The sort operation runs on every render of the project/namespace list
    • Should be memoized with useMemo to avoid unnecessary sorting
const sortedProjects = useMemo(() => {
  return data?.sort((a, b) => {
    if (a.name === project) return -1;
    if (b.name === project) return 1;
    return 0;
  }) ?? [];
}, [data, project]);

Security Concerns ✅

No security issues identified. The code properly:

  • Uses parameterized routing
  • Doesn't expose sensitive data
  • Follows existing authentication patterns

UX & Design

Strengths

  • Progressive disclosure with the 80% threshold for free plans
  • Clear visual hierarchy with warning colors
  • Smooth animations on premium badges add polish
  • Plan badges in context switcher improve discoverability

Questions

  1. Alert Visibility: The alert only shows for free plans at 80%+. Should paid plans also see warnings at higher thresholds (e.g., 90%)?

  2. Button Label Consistency:

    • billing-plans.tsx:159 changes "Cancel" → "Current Plan"
    • plan-card.tsx removes hardcoded button text
    • Ensure all plans show appropriate button states (Current Plan, Upgrade, Downgrade, Contact Us)
  3. Gauge Behavior: The gauge only shows for:

    • Free plans: 50%+
    • Paid plans: 80%+

    This seems intentional but worth confirming the thresholds make sense for your UX goals.

Test Coverage ⚠️

Missing: No tests were added for:

  • BillingLimitAlert component rendering logic
  • Usage percentage calculations
  • Premium badge rendering variants
  • Context switcher sorting behavior

Recommendation: Add unit tests for:

  • Alert visibility logic (plan types, usage thresholds)
  • Gauge rendering at different usage percentages
  • Premium badge variants
  • Sorting logic for current selection

Suggestions

High Priority

  1. Fix the hardcoded 100 limit - use a named constant or revert to RECORDS_PER_PAGE
  2. Add useMemo to the sort operations in context switcher
  3. Document why namespace limit was increased in code comments

Medium Priority

  1. Fix double space in className
  2. Review the justify-center usage in BillingLimitAlert layout
  3. Add unit tests for new components

Low Priority

  1. Consider extracting billing data to shared context to reduce duplicate queries
  2. Consider virtualization for long namespace lists

Summary

This is a well-executed PR that adds valuable user-facing features. The main concern is the hardcoded pagination limit change, which should be addressed before merge. The sorting performance issue is minor but easy to fix. Overall, the code follows good React patterns and the UX improvements are thoughtful.

Recommendation: Request changes for the hardcoded limit issue, then approve after addressed.

Comment on lines +1 to +6
import { faExclamationTriangle, Icon } from "@rivet-gg/icons";
import { useQuery } from "@tanstack/react-query";
import { Link } from "@tanstack/react-router";
import { Button, cn } from "@/components";
import { useCloudProjectDataProvider } from "@/components/actors";
import { useHighestUsagePercent } from "./hooks";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imports should be sorted alphabetically. Reorder to: imports from @/ paths first, then @rivet-gg, then @TanStack, then relative imports.

Spotted by Graphite Agent (based on CI logs)

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@graphite-app
Copy link
Contributor

graphite-app bot commented Jan 31, 2026

Merge activity

  • Jan 31, 2:06 AM UTC: jog1t added this pull request to the Graphite merge queue.
  • Jan 31, 2:06 AM UTC: CI is running for this pull request on a draft pull request (#4084) due to your merge queue CI optimization settings.
  • Jan 31, 2:07 AM UTC: Merged by the Graphite merge queue via draft PR: #4084.

graphite-app bot pushed a commit that referenced this pull request Jan 31, 2026
### TL;DR

Enhanced billing UI with new plan badges, usage alerts, and improved context switcher integration.

### What changed?

- Added a new `BillingLimitAlert` component that displays warnings when approaching or exceeding usage limits
- Enhanced the `BillingPlanBadge` with new styling and support for a "Team" plan tier
- Updated the usage gauge to show different visual indicators based on usage percentage
- Improved the context switcher to display plan badges next to projects and sort current selections to the top
- Updated billing plan card UI with clearer button text and styling
- Added premium badge variants with gradient and animation effects
- Fixed namespace list pagination by increasing the limit from the default to 100

### How to test?

1. Check the billing UI with different usage percentages to see the alerts and gauge changes
2. Verify the new premium badge styling for Team, Pro, and Enterprise plans
3. Open the context switcher to see plan badges next to projects
4. Test the sorting behavior in project and namespace lists
5. Verify that the billing limit alert appears when usage is high on the free plan

### Why make this change?

These changes improve the visibility of billing information throughout the application, making it easier for users to understand their current plan and usage status. The new alerts help prevent unexpected service interruptions by proactively notifying users when they're approaching usage limits. The premium badge styling creates visual distinction between different plan tiers, and the context switcher improvements help users quickly identify which projects are on which plans.
@graphite-app graphite-app bot closed this Jan 31, 2026
@graphite-app graphite-app bot deleted the 01-31-feat_dashboard_add_usage_alerts branch January 31, 2026 02:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant