Skip to content

chore: enhance dashboard components - #1304

Merged
smakosh merged 5 commits into
mainfrom
feat/small-redesign
Dec 7, 2025
Merged

smakosh merged 5 commits into
mainfrom
feat/small-redesign

Conversation

@smakosh

@smakosh smakosh commented Dec 6, 2025 •

Copy link
Copy Markdown
Member

Summary

  • Modified dashboard components to improve functionality and user experience, including the addition of new cards for cost breakdown and recent activity.
  • Refactored the dashboard layout to utilize a quick actions array for better maintainability.

Changes

Dashboard Enhancements

  • Introduced CostBreakdownCard and RecentActivityCard components for improved data visualization.
  • Updated DashboardClient to include average cost metrics and streamlined action buttons.

Rationale

  • Enhances the dashboard's usability and visual appeal, providing users with more actionable insights at a glance.

Test Plan

  • Verify that the new dashboard components render correctly.
  • Ensure that the quick actions function as intended.
  • Confirm that the average cost metric displays accurate data.

Summary by CodeRabbit

  • New Features

    • Referral program: invite & earn dialog with sharing, simulation and earnings preview
    • Dashboard cards: cost breakdown, recent activity, and errors & reliability
    • New slider control for adjustable inputs
    • Avg cost / 1K tokens metric
  • Updates

    • Dashboard charts switched from bar to line visualizations
    • Quick actions made dynamic; upgrade CTA changed to an invite-focused flow
    • Landing features list refreshed; promotional banner text updated
  • Chores

    • Added UI dependency for slider components

✏️ Tip: You can customize this high-level summary in your review settings.

## Summary
- Modified dashboard components to improve functionality and user experience, including the addition of new cards for cost breakdown and recent activity.
- Refactored the dashboard layout to utilize a quick actions array for better maintainability.

## Changes
### Dashboard Enhancements
- Introduced `CostBreakdownCard` and `RecentActivityCard` components for improved data visualization.
- Updated `DashboardClient` to include average cost metrics and streamlined action buttons.

## Rationale
- Enhances the dashboard's usability and visual appeal, providing users with more actionable insights at a glance.

## Test Plan
- [x] Verify that the new dashboard components render correctly.
- [x] Ensure that the quick actions function as intended.
- [x] Confirm that the average cost metric displays accurate data.
@smakosh
smakosh requested a review from steebchen December 6, 2025 23:41
@smakosh smakosh self-assigned this Dec 6, 2025
@coderabbitai

coderabbitai Bot commented Dec 6, 2025 •

Copy link
Copy Markdown
Contributor

Walkthrough

Adds UI components and layout changes: three new dashboard cards (CostBreakdownCard, ErrorsReliabilityCard, RecentActivityCard), a ReferralDialog, a Slider wrapper using Radix, swaps BarChart for LineChart in overview, updates dashboard quick actions and sidebar CTA, and adds @radix-ui/react-slider dependency.

Changes

Cohort / File(s) Summary
Dependency
apps/ui/package.json
Added dependency @radix-ui/react-slider version 1.3.6.
Slider UI
apps/ui/src/lib/components/slider.tsx
New exported Slider component wrapping Radix SliderPrimitive; supports controlled/uncontrolled usage and multiple thumbs.
New Dashboard Cards
apps/ui/src/components/dashboard/cost-breakdown-card.tsx, apps/ui/src/components/dashboard/errors-reliability-card.tsx, apps/ui/src/components/dashboard/recent-activity-card.tsx
Added CostBreakdownCard (renders CostBreakdownChart), ErrorsReliabilityCard (computes error/cache rates and lists worst days), and RecentActivityCard (lists recent daily activity with tokens/costs).
Dashboard Client
apps/ui/src/components/dashboard/dashboard-client.tsx
Integrated new cards into dashboard layout; added avgCostPer1kTokens metric and MetricCard; refactored quick actions to a dynamic array with org-aware URLs; adjusted grid layout to surface new cards.
Sidebar CTA
apps/ui/src/components/dashboard/dashboard-sidebar.tsx
Replaced UpgradeToProDialog flow with ReferralDialog, removed plan gating, and updated CTA copy to referral language.
Referral Dialog
apps/ui/src/components/dashboard/referral-dialog.tsx
New ReferralDialog component (overview & simulation modes), referral link generation, copy-to-clipboard, sliders to estimate credits, and navigation to referral settings.
Overview Chart
apps/ui/src/components/dashboard/overview.tsx
Replaced BarChart/Bar series with LineChart/Line series, added Legend, and adjusted tooltip labeling and series styling.
Landing Content
apps/ui/src/components/landing/features.tsx, apps/ui/src/components/landing/hero.tsx
Removed "Usage Analytics" feature; added four new feature entries; updated hero promo text to "Gemini 3 is now live with a 20% discount".

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to focus:
    • LineChart replacement in overview.tsx: multi-series rendering, legend, tooltip labels and styles.
    • ReferralDialog: referral link composition, clipboard handling, slider integration and navigation triggers.
    • Dashboard client quick actions: org-aware URL construction and navigation targets.
    • Data calculations in new cards: avgCostPer1kTokens, errorRate/cacheRate, empty-data and division-by-zero handling.
    • Slider component: Radix import usage and multiple-thumb rendering behavior.

Possibly related PRs

Suggested reviewers

  • steebchen

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'chore: enhance dashboard components' is vague and generic, using non-descriptive terms that don't convey the specific changes made in the changeset. Consider a more specific title that highlights the main changes, such as 'feat: add cost breakdown and recent activity dashboard cards' or 'refactor: improve dashboard layout with new cards and quick actions.'
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/small-redesign

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@steebchen

Copy link
Copy Markdown
Member

Images automagically compressed by Calibre's image-actions ✨

Compression reduced images by 71.5%, saving 1.2 MB.

Filename Before After Improvement Visual comparison
apps/ui/public/new-hero.png 416.7 KB 104.0 KB 75.0% View diff
apps/playground/public/opengraph.png 428.3 KB 117.3 KB 72.6% View diff
apps/ui/public/opengraph.png 428.0 KB 132.9 KB 68.9% View diff
apps/ui/public/new-hero-light.png 409.4 KB 125.0 KB 69.5% View diff

@steebchen

Copy link
Copy Markdown
Member

Images automagically compressed by Calibre's image-actions ✨

Compression reduced images by 12.7%, saving 16.9 KB.

Filename Before After Improvement Visual comparison
apps/ui/public/opengraph.png 132.9 KB 116.0 KB 12.7% View diff

3 images did not require optimisation.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (6)
apps/ui/src/components/landing/hero.tsx (1)

149-156: Promo banner text and target link may now be misaligned

You’ve updated the banner to “Gemini 3 is now live with a 20% discount”, but the link still points to /changelog/gemini-3-pro-preview-support. If this page is still about a “preview” or doesn’t mention the discount, users may be confused. Consider updating the target to a more appropriate page and/or moving the discount copy into config so the percentage/promo can be changed without a code deploy.

apps/ui/src/components/landing/features.tsx (1)

181-270: New analytics feature cards look consistent; consider minor copy + a11y polish

The new feature entries are structurally consistent with the existing ones (same icon/title/description pattern) and the marketing copy matches the new dashboard capabilities described in the PR.

A couple of small, optional improvements you might consider:

  • Add aria-hidden="true" to these new <svg> icons (and ideally all feature icons in this file in a follow‑up) so screen readers don’t try to interpret the decorative SVG shapes.
  • Double‑check that the time ranges and metrics mentioned in the copy (e.g. “7 or 30 days”, “average cost per 1K tokens”, “cache hit rate”) precisely match the labels and behavior in the dashboard cards to avoid subtle wording drift.

Example for one icon (apply similarly to the other new SVGs if you want this change now):

-			<svg
-				className="h-8 w-8"
-				fill="none"
-				xmlns="http://www.w3.org/2000/svg"
-				viewBox="0 0 144 144"
-			>
+			<svg
+				className="h-8 w-8"
+				fill="none"
+				xmlns="http://www.w3.org/2000/svg"
+				viewBox="0 0 144 144"
+				aria-hidden="true"
+			>
apps/ui/src/components/dashboard/overview.tsx (1)

155-167: Consider using a render function for cleaner Tooltip content.

The hardcoded placeholder props (label="tooltip", active={true}, payload={[{ value: 0 }]}) are confusing since recharts overrides them at runtime via cloneElement. Using a render function is more idiomatic and clearer:

 <Tooltip
-  content={
-    <CustomTooltip
-      active={true}
-      payload={[{ value: 0 }]}
-      label="tooltip"
-      metric={metric}
-    />
-  }
+  content={(props) => (
+    <CustomTooltip
+      active={props.active ?? false}
+      payload={props.payload ?? []}
+      label={String(props.label ?? "")}
+      metric={metric}
+    />
+  )}
   cursor={{
     fill: "color-mix(in srgb, currentColor 15%, transparent)",
   }}
 />
apps/ui/src/components/dashboard/dashboard-sidebar.tsx (1)

36-36: Referral CTA integration in sidebar looks correct; consider renaming for clarity.

The new referral-focused CTA is correctly gated on show && selectedOrganization and passes selectedOrganization into ReferralDialog, which matches that component’s expectations.

Optionally, you might later rename UpgradeCTA and the upgradeCTA_dismissed localStorage key to something referral‑specific to better reflect the new behavior, but this is purely cosmetic.

Also applies to: 613-645

apps/ui/src/components/dashboard/recent-activity-card.tsx (1)

24-58: Recent activity card logic is solid; minor optional cleanups.

The loading/empty/data flows and the 7‑day slice are clear and correct. Two small optional tweaks:

  • Make the sort comparator handle equal dates explicitly for readability:
    const latestDays = [...activityData]
    	.sort((a, b) =>
    		a.date === b.date ? 0 : a.date < b.date ? 1 : -1,
    	)
    	.slice(0, 7);
  • Consider extracting the shared “Recent Activity” header + fixed-height body wrapper used in the loading and empty states into a small helper component to avoid duplication.

Also applies to: 68-91

apps/ui/src/components/dashboard/referral-dialog.tsx (1)

52-65: Referral dialog behavior is sound; a couple of small robustness tweaks are possible.

Two optional refinements:

  • When !selectedOrganization, you do return children as ReactElement;. This assumes children is always a single element. If there’s any chance of passing a fragment or string, consider returning <>{children}</> instead to avoid runtime issues.
  • The slider handlers already destructure the first value, so the type checks are redundant. You can simplify to:
    onValueChange={([value]) => setReferredTeams(value)}
    // ...
    onValueChange={([value]) => setAvgMonthlySpend(value)}

These don’t change behavior but slightly tighten up the implementation.

Also applies to: 247-280

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1799374 and 9c7f48e.

⛔ Files ignored due to path filters (5)
  • apps/playground/public/opengraph.png is excluded by !**/*.png
  • apps/ui/public/new-hero-light.png is excluded by !**/*.png
  • apps/ui/public/new-hero.png is excluded by !**/*.png
  • apps/ui/public/opengraph.png is excluded by !**/*.png
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • apps/ui/package.json (1 hunks)
  • apps/ui/src/components/dashboard/cost-breakdown-card.tsx (1 hunks)
  • apps/ui/src/components/dashboard/dashboard-client.tsx (4 hunks)
  • apps/ui/src/components/dashboard/dashboard-sidebar.tsx (4 hunks)
  • apps/ui/src/components/dashboard/errors-reliability-card.tsx (1 hunks)
  • apps/ui/src/components/dashboard/overview.tsx (3 hunks)
  • apps/ui/src/components/dashboard/recent-activity-card.tsx (1 hunks)
  • apps/ui/src/components/dashboard/referral-dialog.tsx (1 hunks)
  • apps/ui/src/components/landing/features.tsx (1 hunks)
  • apps/ui/src/components/landing/hero.tsx (1 hunks)
  • apps/ui/src/lib/components/slider.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Never use any or as any unless absolutely necessary in TypeScript code
For database reads: Use db().query.<table>.findMany() or db().query.<table>.findFirst()

Files:

  • apps/ui/src/components/landing/hero.tsx
  • apps/ui/src/lib/components/slider.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/recent-activity-card.tsx
  • apps/ui/src/components/dashboard/errors-reliability-card.tsx
  • apps/ui/src/components/dashboard/dashboard-sidebar.tsx
  • apps/ui/src/components/dashboard/cost-breakdown-card.tsx
  • apps/ui/src/components/dashboard/overview.tsx
  • apps/ui/src/components/landing/features.tsx
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use tabs for indentation

Files:

  • apps/ui/src/components/landing/hero.tsx
  • apps/ui/src/lib/components/slider.tsx
  • apps/ui/package.json
  • apps/ui/src/components/dashboard/referral-dialog.tsx
  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/recent-activity-card.tsx
  • apps/ui/src/components/dashboard/errors-reliability-card.tsx
  • apps/ui/src/components/dashboard/dashboard-sidebar.tsx
  • apps/ui/src/components/dashboard/cost-breakdown-card.tsx
  • apps/ui/src/components/dashboard/overview.tsx
  • apps/ui/src/components/landing/features.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Always use top-level import, never use require or dynamic imports
No unnecessary code comments

Files:

  • apps/ui/src/components/landing/hero.tsx
  • apps/ui/src/lib/components/slider.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/recent-activity-card.tsx
  • apps/ui/src/components/dashboard/errors-reliability-card.tsx
  • apps/ui/src/components/dashboard/dashboard-sidebar.tsx
  • apps/ui/src/components/dashboard/cost-breakdown-card.tsx
  • apps/ui/src/components/dashboard/overview.tsx
  • apps/ui/src/components/landing/features.tsx
apps/{ui,playground}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{ui,playground}/**/*.{ts,tsx}: Use cookies for user-settings which are not saved in the database to ensure SSR works
Use Next.js App Router with React Server Components for frontend development

Use cookies for user-settings which are not saved in the database to ensure SSR works

Files:

  • apps/ui/src/components/landing/hero.tsx
  • apps/ui/src/lib/components/slider.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/recent-activity-card.tsx
  • apps/ui/src/components/dashboard/errors-reliability-card.tsx
  • apps/ui/src/components/dashboard/dashboard-sidebar.tsx
  • apps/ui/src/components/dashboard/cost-breakdown-card.tsx
  • apps/ui/src/components/dashboard/overview.tsx
  • apps/ui/src/components/landing/features.tsx
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always use top-level import, never use require or dynamic imports

Files:

  • apps/ui/src/components/landing/hero.tsx
  • apps/ui/src/lib/components/slider.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/recent-activity-card.tsx
  • apps/ui/src/components/dashboard/errors-reliability-card.tsx
  • apps/ui/src/components/dashboard/dashboard-sidebar.tsx
  • apps/ui/src/components/dashboard/cost-breakdown-card.tsx
  • apps/ui/src/components/dashboard/overview.tsx
  • apps/ui/src/components/landing/features.tsx
apps/{ui,playground,docs}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use next/link for links and next/navigation's router for programmatic navigation

Files:

  • apps/ui/src/components/landing/hero.tsx
  • apps/ui/src/lib/components/slider.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/recent-activity-card.tsx
  • apps/ui/src/components/dashboard/errors-reliability-card.tsx
  • apps/ui/src/components/dashboard/dashboard-sidebar.tsx
  • apps/ui/src/components/dashboard/cost-breakdown-card.tsx
  • apps/ui/src/components/dashboard/overview.tsx
  • apps/ui/src/components/landing/features.tsx
🧬 Code graph analysis (3)
apps/ui/src/components/dashboard/recent-activity-card.tsx (2)
apps/ui/src/types/activity.ts (1)
  • DailyActivity (13-30)
apps/ui/src/lib/components/card.tsx (1)
  • Card (85-85)
apps/ui/src/components/dashboard/errors-reliability-card.tsx (2)
apps/ui/src/types/activity.ts (1)
  • DailyActivity (13-30)
apps/ui/src/lib/components/card.tsx (5)
  • Card (85-85)
  • CardHeader (86-86)
  • CardTitle (88-88)
  • CardDescription (90-90)
  • CardContent (91-91)
apps/ui/src/components/dashboard/dashboard-sidebar.tsx (1)
apps/ui/src/components/dashboard/referral-dialog.tsx (1)
  • ReferralDialog (34-303)
⏰ 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). (10)
  • GitHub Check: build-split (worker, linux/amd64)
  • GitHub Check: build-split (playground, linux/amd64)
  • GitHub Check: build-split (ui, linux/amd64)
  • GitHub Check: build-split (gateway, linux/amd64)
  • GitHub Check: build-unified (linux/amd64)
  • GitHub Check: test / run
  • GitHub Check: lint / run
  • GitHub Check: build / run
  • GitHub Check: generate / run
  • GitHub Check: autofix
🔇 Additional comments (6)
apps/ui/src/components/dashboard/overview.tsx (2)

168-173: LGTM!

The Legend configuration with top-left positioning and circle icons provides good visual context for the multi-series line chart.


174-202: LGTM!

The Line chart implementation is well-configured:

  • type="monotone" provides smooth curves appropriate for time-series data
  • dot={false} reduces clutter on daily data points
  • Semantically meaningful colors (green for savings, blue for cost/requests)
apps/ui/src/components/dashboard/cost-breakdown-card.tsx (1)

15-39: Cost breakdown card wiring looks good.

Props, selected project usage, and CostBreakdownChart wiring are straightforward and type‑safe; no issues from this diff.

apps/ui/src/components/dashboard/dashboard-client.tsx (1)

116-133: New metrics and analytics cards are well-integrated.

The aggregate totals, avgCostPer1kTokens calculation (guarded on totalTokens > 0), and the new MetricCard plus CostBreakdown/RecentActivity/Errors cards are all wired correctly and respect the existing shouldShowGetStartedState gating. This looks good.

Also applies to: 343-357, 423-441

apps/ui/src/components/dashboard/errors-reliability-card.tsx (1)

20-75: Error and cache metrics computation looks correct.

Totals, percentage calculations (with proper zero‑request guards), and “worst days” selection are all implemented cleanly and handle no‑data cases gracefully. No issues from this diff.

Also applies to: 77-138

apps/ui/package.json (1)

40-40: Indentation and version pinning are correct.

The @radix-ui/react-slider dependency uses tabs for indentation (per guidelines) and is already locked in pnpm-lock.yaml. The pinned version 1.3.6 is consistent with other Radix dependencies in the file (e.g., react-accordion, react-avatar, react-dropdown-menu). The slider component is imported in apps/ui/src/lib/components/slider.tsx, confirming active usage.

Comment thread apps/ui/src/components/dashboard/dashboard-client.tsx
Comment thread apps/ui/src/components/dashboard/referral-dialog.tsx
Comment thread apps/ui/src/lib/components/slider.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (2)
apps/ui/src/components/dashboard/referral-dialog.tsx (2)

56-57: Encode the referral ID in the query parameter.

To guard against unexpected characters in selectedOrganization.id breaking the URL, encode the value when building the referral link.

-	const referralLink = `${origin}/?ref=${selectedOrganization.id}`;
+	const referralLink = `${origin}/?ref=${encodeURIComponent(
+		selectedOrganization.id,
+	)}`;

247-279: Simplify Slider onValueChange handlers for clarity.

Current array destructuring works but is a bit opaque; indexing the first element reads clearer and matches the Slider’s number[] API.

-									<Slider
-										min={0}
-										max={50}
-										step={1}
-										value={[referredTeams]}
-										onValueChange={([value]) =>
-											setReferredTeams(typeof value === "number" ? value : 0)
-										}
-									/>
+									<Slider
+										min={0}
+										max={50}
+										step={1}
+										value={[referredTeams]}
+										onValueChange={(values) =>
+											setReferredTeams(
+												typeof values[0] === "number" ? values[0] : 0,
+											)
+										}
+									/>
@@
-									<Slider
-										min={50}
-										max={5000}
-										step={50}
-										value={[avgMonthlySpend]}
-										onValueChange={([value]) =>
-											setAvgMonthlySpend(typeof value === "number" ? value : 0)
-										}
-									/>
+									<Slider
+										min={50}
+										max={5000}
+										step={50}
+										value={[avgMonthlySpend]}
+										onValueChange={(values) =>
+											setAvgMonthlySpend(
+												typeof values[0] === "number" ? values[0] : 0,
+											)
+										}
+									/>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9c7f48e and a498c97.

📒 Files selected for processing (2)
  • apps/ui/src/components/dashboard/dashboard-client.tsx (5 hunks)
  • apps/ui/src/components/dashboard/referral-dialog.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Never use any or as any unless absolutely necessary in TypeScript code
For database reads: Use db().query.<table>.findMany() or db().query.<table>.findFirst()

Files:

  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use tabs for indentation

Files:

  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Always use top-level import, never use require or dynamic imports
No unnecessary code comments

Files:

  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
apps/{ui,playground}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{ui,playground}/**/*.{ts,tsx}: Use cookies for user-settings which are not saved in the database to ensure SSR works
Use Next.js App Router with React Server Components for frontend development

Use cookies for user-settings which are not saved in the database to ensure SSR works

Files:

  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always use top-level import, never use require or dynamic imports

Files:

  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
apps/{ui,playground,docs}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use next/link for links and next/navigation's router for programmatic navigation

Files:

  • apps/ui/src/components/dashboard/dashboard-client.tsx
  • apps/ui/src/components/dashboard/referral-dialog.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-03T12:42:14.208Z
Learnt from: CR
Repo: theopenco/llmgateway PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T12:42:14.208Z
Learning: Applies to apps/{ui,playground}/**/*.{tsx} : Use `next/link` for links and `next/navigation`'s router for programmatic navigation

Applied to files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
📚 Learning: 2025-12-03T12:42:26.143Z
Learnt from: CR
Repo: theopenco/llmgateway PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T12:42:26.143Z
Learning: Applies to apps/{ui,playground,docs}/**/*.{ts,tsx} : Use `next/link` for links and `next/navigation`'s router for programmatic navigation

Applied to files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
📚 Learning: 2025-12-03T12:42:14.208Z
Learnt from: CR
Repo: theopenco/llmgateway PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T12:42:14.208Z
Learning: Applies to apps/{ui,playground}/**/*.{ts,tsx} : Use Next.js App Router with React Server Components for frontend development

Applied to files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
🧬 Code graph analysis (2)
apps/ui/src/components/dashboard/dashboard-client.tsx (4)
apps/ui/src/hooks/useDashboardNavigation.ts (1)
  • useDashboardNavigation (15-49)
apps/ui/src/components/dashboard/cost-breakdown-card.tsx (1)
  • CostBreakdownCard (19-40)
apps/ui/src/components/dashboard/recent-activity-card.tsx (1)
  • RecentActivityCard (20-96)
apps/ui/src/components/dashboard/errors-reliability-card.tsx (1)
  • ErrorsReliabilityCard (20-139)
apps/ui/src/components/dashboard/referral-dialog.tsx (1)
apps/ui/src/lib/components/slider.tsx (1)
  • Slider (63-63)
⏰ 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). (5)
  • GitHub Check: autofix
  • GitHub Check: test / run
  • GitHub Check: build / run
  • GitHub Check: generate / run
  • GitHub Check: lint / run
🔇 Additional comments (9)
apps/ui/src/components/dashboard/dashboard-client.tsx (7)

21-25: LGTM!

New card component imports follow project conventions and coding guidelines for top-level imports.


56-56: LGTM!

Good fix—importing buildOrgUrl enables proper org-scoped routing for provider keys, addressing the issue flagged in the previous review.


131-132: LGTM!

The average cost calculation correctly handles division by zero and scales appropriately for the per-1K-tokens metric.


134-160: LGTM!

The quick actions array provides good maintainability. The provider-keys routing is correctly handled in the render logic below.


349-357: LGTM!

The new metric card follows the established pattern with proper loading state handling and consistent styling.


406-425: LGTM!

The refactored quick actions correctly use buildOrgUrl for the org-scoped provider-keys route while maintaining project-scoped routes for other actions. This properly addresses the routing issue from the previous review.


435-440: No action needed—CostBreakdownChart handles its own data fetching.

CostBreakdownChart is a client component that uses useApi().useQuery() to fetch data from the /activity endpoint (lines 56–71). It passes the initialData prop to useQuery for SSR hydration, then actively fetches fresh data and responds to the days URL parameter. When users toggle between 7 and 30 days, the component re-fetches and updates accordingly. The data source pattern is correct and intentional.

apps/ui/src/components/dashboard/referral-dialog.tsx (2)

34-45: Client component and router setup look good.

Using "use client" plus useRouter from next/navigation and local state for dialog/mode is aligned with the App Router guidance and repo conventions.
Based on learnings, this matches the Next.js navigation pattern we want in apps/ui.


195-201: Confirm that /settings/referral is the correct, org-aware route.

Please double‑check that /settings/referral is the intended destination and that it correctly handles the currently selected organization (previous code used an org‑scoped helper). If referral settings are per‑org, you may want to keep using the org‑aware URL builder or include the org identifier in the route.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (3)
apps/ui/src/components/dashboard/referral-dialog.tsx (3)

54-56: Type assertion may be unsafe for non-element children.

The cast children as ReactElement assumes children is always a single element, but ReactNode can be a fragment, array, or multiple elements. If the trigger wraps multiple children or a fragment, this could cause TypeScript to miss issues.

Consider one of these approaches:

Option 1: Return children directly (React handles ReactNode)

 if (!selectedOrganization) {
-  return children as ReactElement;
+  return <>{children}</>;
 }

Option 2: Adjust the return type annotation

If the component must return ReactElement, change the prop type to enforce it:

 interface ReferralDialogProps {
-  children: ReactNode;
+  children: ReactElement;
   selectedOrganization: Organization | null;
 }

59-60: Simplify redundant fallback.

The outer || 0 is redundant since Number(x || 0) already returns 0 when the input is falsy.

-const referralEarnings =
-  Number(selectedOrganization.referralEarnings || 0) || 0;
+const referralEarnings = Number(selectedOrganization.referralEarnings || 0);

255-263: Simplify slider callbacks.

The type guards typeof value === "number" ? value : 0 are defensive but likely unnecessary. The Radix UI Slider component's onValueChange callback receives a number array, so the destructured value should always be a number. The fallback to 0 would only trigger if the Slider implementation violates its own contract.

If you prefer to keep the defensive check for safety, the current code is fine. Otherwise, simplify:

 <Slider
   min={0}
   max={50}
   step={1}
   value={[referredTeams]}
-  onValueChange={([value]) =>
-    setReferredTeams(typeof value === "number" ? value : 0)
-  }
+  onValueChange={([value]) => setReferredTeams(value)}
 />
 <Slider
   min={50}
   max={5000}
   step={50}
   value={[avgMonthlySpend]}
-  onValueChange={([value]) =>
-    setAvgMonthlySpend(typeof value === "number" ? value : 0)
-  }
+  onValueChange={([value]) => setAvgMonthlySpend(value)}
 />

Also applies to: 272-280

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a498c97 and 140f15d.

📒 Files selected for processing (1)
  • apps/ui/src/components/dashboard/referral-dialog.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Never use any or as any unless absolutely necessary in TypeScript code
For database reads: Use db().query.<table>.findMany() or db().query.<table>.findFirst()

Files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use tabs for indentation

Files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Always use top-level import, never use require or dynamic imports
No unnecessary code comments

Files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
apps/{ui,playground}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{ui,playground}/**/*.{ts,tsx}: Use cookies for user-settings which are not saved in the database to ensure SSR works
Use Next.js App Router with React Server Components for frontend development

Use cookies for user-settings which are not saved in the database to ensure SSR works

Files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always use top-level import, never use require or dynamic imports

Files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
apps/{ui,playground,docs}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use next/link for links and next/navigation's router for programmatic navigation

Files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-03T12:42:14.208Z
Learnt from: CR
Repo: theopenco/llmgateway PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T12:42:14.208Z
Learning: Applies to apps/{ui,playground}/**/*.{tsx} : Use `next/link` for links and `next/navigation`'s router for programmatic navigation

Applied to files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
📚 Learning: 2025-12-03T12:42:26.143Z
Learnt from: CR
Repo: theopenco/llmgateway PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T12:42:26.143Z
Learning: Applies to apps/{ui,playground,docs}/**/*.{ts,tsx} : Use `next/link` for links and `next/navigation`'s router for programmatic navigation

Applied to files:

  • apps/ui/src/components/dashboard/referral-dialog.tsx
📚 Learning: 2025-12-03T12:42:14.208Z
Learnt from: CR
Repo: theopenco/llmgateway PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T12:42:14.208Z
Learning: Applies to apps/{ui,playground}/**/*.{ts,tsx} : Use Next.js App Router with React Server Components for frontend development

Applied to files:

  • apps/ui/src/components/dashboard/referral-dialog.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). (13)
  • GitHub Check: build-split (worker, linux/amd64)
  • GitHub Check: build-split (docs, linux/amd64)
  • GitHub Check: build-split (playground, linux/amd64)
  • GitHub Check: build-split (gateway, linux/amd64)
  • GitHub Check: build-split (admin, linux/amd64)
  • GitHub Check: build-split (ui, linux/amd64)
  • GitHub Check: build-split (api, linux/amd64)
  • GitHub Check: build-unified (linux/amd64)
  • GitHub Check: test / run
  • GitHub Check: generate / run
  • GitHub Check: build / run
  • GitHub Check: lint / run
  • GitHub Check: autofix

Comment thread apps/ui/src/components/dashboard/referral-dialog.tsx
@smakosh
smakosh added this pull request to the merge queue Dec 7, 2025
Merged via the queue into main with commit 127ffe2 Dec 7, 2025
22 checks passed
@smakosh
smakosh deleted the feat/small-redesign branch December 7, 2025 00:12
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.

2 participants