Skip to content

Dashboard: Analytics Dashboard Page#183

Merged
Ayush8923 merged 14 commits into
mainfrom
feat/dashboard-analytics-page
Jun 3, 2026
Merged

Dashboard: Analytics Dashboard Page#183
Ayush8923 merged 14 commits into
mainfrom
feat/dashboard-analytics-page

Conversation

@Ayush8923
Copy link
Copy Markdown
Collaborator

@Ayush8923 Ayush8923 commented May 25, 2026

Issue: #182

Summary:

  • Adds a new Dashboard page that gives users a single place to track how their API usage and evaluation activity is trending over time. It replaces the need to dig through individual screens to understand cost and volume, everything is now visible in one analytics view, with flexible filters and breakdowns.

    What users can do

    • Track four key metrics

      • Number of requests
      • LLM cost (USD)
      • Number of eval runs
      • Eval cost (USD)
    • Break the data down by:

      • Total (no breakdown)
      • Provider (OpenAI, Anthropic, etc.)
      • Request type (Text → Text, Speech → Speech, STT, TTS, Other)
      • Request type + Provider combined
    • Filter the view by:

      • Request type (modality)
      • Provider
      • A custom month range (From / To), with a quick "Clear dates" reset
  • See totals at a glance — a summary row shows the aggregated totals for the currently applied filters, alongside total input/output tokens where applicable.

  • Visualise trends over time — a monthly chart plots the selected metric, automatically updating when filters or grouping change

  • Navigate easily — a new "Dashboard" entry has been added to the sidebar with a chart icon, so the page is reachable from anywhere in the app.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Review Change Stack

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • ready-for-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b378e8cd-fa88-400e-97b5-9703c3907c30

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR implements a complete analytics dashboard feature. It adds type contracts for analytics metrics and filtering, an API route handler that proxies requests to the backend, utility functions to normalize and merge series data, React hooks for chart and totals data fetching, Recharts-based chart and breakdown components, an all-time totals summary row, a dashboard page that orchestrates filters and displays the data, sidebar navigation integration, and enhancements to the Select component including optional grouping support.

Changes

Analytics Dashboard

Layer / File(s) Summary
Analytics and UI type contracts
app/lib/types/analytics.ts, app/lib/types/ui.ts
Defines AnalyticsMetric (including virtual metrics cost_all and volume), AnalyticsGroupBy, AnalyticsModality, chart data shapes with optional token totals, filter inputs, tooltip types, and totals aggregation types; refactors SelectOption to centralized ui.ts.
API route handler for analytics data
app/api/analytics/monthly/chart/route.ts
GET route that forwards query parameters to a versioned analytics endpoint via apiClient, returns upstream data/status, and standardizes error responses.
Series normalization, merging, and formatting utilities
app/lib/utils/analytics/normalizeSeries.ts, app/lib/utils/analytics/mergeChartData.ts, app/lib/utils/analytics/formatValue.ts
Canonicalizes provider identifiers into display names and merges series with identical normalized names by summing data and aggregating tokens; provides formatters for currency-aware metric display, compact k/M notation, and month labels.
useAnalyticsChart hook for line chart data
app/hooks/useAnalyticsChart.ts
Fetches chart data from /api/analytics/monthly/chart, expands virtual metrics into parallel atomic requests, merges results via mergeChartData, and exposes data/isLoading/error/refetch; gated by authentication.
useAnalyticsTotals hook for all-time totals
app/hooks/useAnalyticsTotals.ts
Fetches a fixed metrics list in parallel, reduces series into summed numeric values and aggregated token counts per metric, and returns totals/isLoading/error; gated by authentication.
Chart visualization components
app/components/analytics/LineTrendChart.tsx, app/components/analytics/ChartTooltip.tsx, app/components/analytics/BreakdownPanel.tsx
LineTrendChart renders responsive Recharts composed chart with per-series lines, optional total line, legend, and custom tooltip. ChartTooltip formats values by metric. BreakdownPanel renders pie/donut chart with segmented table showing share and token breakdown.
AnalyticsChartCard composite component
app/components/analytics/AnalyticsChartCard.tsx
Orchestrates chart rendering: normalizes and filters series, computes per-month totals and min/max ranges, trims zero-tail months, renders header with tooltip, optional BreakdownPanel, LineTrendChart with per-series coloring, and optional token summary cards.
AnalyticsTotalsRow all-time totals component
app/components/analytics/AnalyticsTotalsRow.tsx
Renders all-time totals as a responsive grid with six stat cards: requests, cost (production/eval), and token counts (production/eval); uses compact and currency formatting; includes loading/error states.
MonthYearPicker date range control
app/components/analytics/MonthYearPicker.tsx
Popover-based month/year picker allowing date range selection within a computed allowed window; emits YYYY-MM-01 ISO strings and manages year/month view transitions.
Analytics components barrel exports
app/components/analytics/index.ts
Re-exports AnalyticsChartCard, AnalyticsTotalsRow, ChartTooltip, and MonthYearPicker.
Analytics option lists and constants
app/lib/constants.ts
Exported option lists (ANALYTICS_METRIC_OPTIONS, ANALYTICS_GROUP_BY_OPTIONS, ANALYTICS_MODALITY_OPTIONS, MONTH_OPTIONS) and helper to generate recent year options.
Analytics dashboard page and filter orchestration
app/(main)/analytics/page.tsx
Client dashboard page managing filter state (metric, group_by, modality, provider, from/to months); renders sticky filter controls using Select and MonthYearPicker; gates on auth hydration; wires chart/totals hooks to display components.
Icon components and navigation integration
app/components/icons/common/TooltipIcon.tsx, app/components/icons/sidebar/ChartBarIcon.tsx, app/components/icons/index.tsx, app/components/Sidebar.tsx, app/lib/navConfig.ts
Adds TooltipIcon and ChartBarIcon SVG components; updates sidebar iconMap to render ChartBarIcon for chart key; adds Analytics navigation item with login gating to NAV_ITEMS.
Select component enhancement and UI consolidation
app/components/ui/Select.tsx, app/components/ui/index.ts, app/components/ui/InfoTooltip.tsx, app/components/prompt-editor/DiffView.tsx, app/lib/utils/selectOptions.ts
Moves SelectOption type to centralized ui.ts; adds grouped option support to Select via optgroup rendering; updates InfoTooltip to render TooltipIcon; consolidates imports to use new type location; adds toSelectOptions utility.
Scrollbar styling
app/globals.css
Adds .custom-scroll-accent class with WebKit and Firefox scrollbar styling using accent-colored thumb.
Recharts charting library dependency
package.json
Adds recharts v^3.8.1 as a runtime dependency.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • vprashrex
  • Prajna1999

Poem

📊 A dashboard blooms with lines and charts so bright,
Series merge and normalize, tokens dance in light,
Hooks fetch data, filters fine-tune the view,
From types to tooltips, this feature's built brand new! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title "Dashboard: Analytics Dashboard Page" clearly and concisely summarizes the main change—the addition of a new Analytics Dashboard page with its key features.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dashboard-analytics-page

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.

@Ayush8923 Ayush8923 changed the title Dashboard: Analytics Dashboard Dashboard: Analytics Dashboard Page May 25, 2026
@Ayush8923 Ayush8923 linked an issue May 25, 2026 that may be closed by this pull request
@Ayush8923 Ayush8923 self-assigned this May 25, 2026
@Ayush8923 Ayush8923 requested a review from vprashrex May 26, 2026 04:29
@Ayush8923 Ayush8923 removed the request for review from vprashrex May 26, 2026 04:33
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/components/analytics/AnalyticsChartCard.tsx (1)

1-502: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Split this component to stay under the TS/TSX file size limit.

This file is over the 500 LOC limit and should be split (for example: tooltip, token stat card, and chart formatting helpers into separate modules/hooks).

As per coding guidelines, **/*.{ts,tsx}: “Do not let any file exceed 500 lines of code (LOC). If a file is approaching or has crossed this limit, split it into smaller modules by extracting sub-components, hooks, utilities, or types into their own files.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/analytics/AnalyticsChartCard.tsx` around lines 1 - 502, This
component exceeds the 500 LOC limit; split it by extracting subcomponents and
helpers: move ChartTooltip into its own component file (exporting
TooltipEntry/TooltipRenderProps types), move TokenStat into its own component
file, and extract the chart helper functions/consts (SERIES_COLORS,
CURRENCY_METRICS, formatMonthLabel, formatValue, formatTokens, formatAxisValue,
buildRows) into a chartUtils module that exports them and the ChartRow type;
update AnalyticsChartCard to import those new modules and keep logic in-place
(retain normalizeAndMergeSeries usage and activeData/totals/tokenSummary
computations). Ensure names remain unchanged (ChartTooltip, TokenStat,
buildRows, formatValue, etc.) so imports are straightforward and tests/refs keep
working.
🧹 Nitpick comments (1)
app/components/analytics/AnalyticsTotalsRow.tsx (1)

13-19: ⚡ Quick win

Extract formatTokens to a shared analytics formatter utility.

This formatter is duplicated across analytics components; centralizing it will keep token formatting consistent and reduce drift.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/analytics/AnalyticsTotalsRow.tsx` around lines 13 - 19, The
formatTokens function is duplicated across analytics components; extract it into
a shared utility and replace local copies with an import. Create a new exported
helper (e.g., formatTokens) in a shared module like analytics/formatters or
utils/analytics, move the existing logic from AnalyticsTotalsRow.tsx into that
module, update AnalyticsTotalsRow.tsx to import and use the shared formatTokens,
and ensure any other components using the same logic import the same helper to
keep formatting consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/`(main)/dashboard/page.tsx:
- Around line 89-92: The flush function currently only clears the parent when
both year and month are empty, leaving a stale filter if one of them is cleared;
update flush (the const flush = (y: string, m: string) => { ... } function) to
call onChange("") whenever either y or m is falsy (i.e., replace the else-if
branch with a default else that calls onChange("")); keep the existing case
where both y and m produce `${y}-${m}-01`, and ensure you use the same onChange
symbol so the parent always receives an empty value when the date is incomplete.

In `@app/api/analytics/monthly/chart/route.ts`:
- Around line 11-17: In the catch block of the route handler replace the current
ad-hoc error stringification with the standardized extractor: call the
extractErrorMessage(errorBody, error instanceof Error ? error.message : 'Unknown
error') utility and use its return value for the error field in the
NextResponse.json payload; update the catch path that currently constructs error
via error instanceof Error ? error.message : String(error) so it invokes
extractErrorMessage and passes that result into NextResponse.json instead.

In `@app/components/analytics/AnalyticsTotalsRow.tsx`:
- Around line 5-10: The prop type AnalyticsTotalsMap is imported from a hook
module but should be moved to shared types; create or export the
AnalyticsTotalsMap type in app/lib/types (or add an appropriate export if it
already exists) and update the import in AnalyticsTotalsRow.tsx to import {
AnalyticsTotalsMap } from "app/lib/types" (replace the current import from
"`@/app/hooks/useAnalyticsTotals`"); ensure any other consumers of
AnalyticsTotalsMap use the shared type export and remove the hook-local type to
avoid boundary coupling.

In `@app/hooks/useAnalyticsChart.ts`:
- Around line 41-62: fetchChart can suffer from race conditions where an older
overlapping fetch resolves after a newer one and overwrites state; fix by adding
a latest-request guard: create a stable ref/variable (e.g., latestRequestIdRef)
incremented each time fetchChart starts, capture the current id in the async
call, and before calling setData/setError/setIsLoading verify the captured id
matches latestRequestIdRef.current (only the latest invocation may update
state); implement this guard inside fetchChart (and any other similar fetch in
this hook) and ensure the ref is initialized with useRef so it survives renders
and is checked in the try/catch/finally blocks.

In `@app/hooks/useAnalyticsTotals.ts`:
- Around line 69-112: fetchTotals can have out-of-order async completions that
overwrite newer state; add a request-sequencing guard using a ref counter (e.g.,
requestSeqRef) that you increment before starting the async work, capture the
current seq in a local variable, and then only call setTotals, setError, and
setIsLoading if the captured seq equals the current ref value; apply the same
pattern to any other async flows mentioned (lines ~114-116) so stale responses
are ignored and only the latest request wins, keeping fetchTotals, setTotals,
setError, setIsLoading and filtersKey as the points of reference when locating
where to add the guard.

---

Outside diff comments:
In `@app/components/analytics/AnalyticsChartCard.tsx`:
- Around line 1-502: This component exceeds the 500 LOC limit; split it by
extracting subcomponents and helpers: move ChartTooltip into its own component
file (exporting TooltipEntry/TooltipRenderProps types), move TokenStat into its
own component file, and extract the chart helper functions/consts
(SERIES_COLORS, CURRENCY_METRICS, formatMonthLabel, formatValue, formatTokens,
formatAxisValue, buildRows) into a chartUtils module that exports them and the
ChartRow type; update AnalyticsChartCard to import those new modules and keep
logic in-place (retain normalizeAndMergeSeries usage and
activeData/totals/tokenSummary computations). Ensure names remain unchanged
(ChartTooltip, TokenStat, buildRows, formatValue, etc.) so imports are
straightforward and tests/refs keep working.

---

Nitpick comments:
In `@app/components/analytics/AnalyticsTotalsRow.tsx`:
- Around line 13-19: The formatTokens function is duplicated across analytics
components; extract it into a shared utility and replace local copies with an
import. Create a new exported helper (e.g., formatTokens) in a shared module
like analytics/formatters or utils/analytics, move the existing logic from
AnalyticsTotalsRow.tsx into that module, update AnalyticsTotalsRow.tsx to import
and use the shared formatTokens, and ensure any other components using the same
logic import the same helper to keep formatting consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cc4872dc-011f-4efa-9aa0-922a7ca3d365

📥 Commits

Reviewing files that changed from the base of the PR and between 4e76625 and 48032df.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (14)
  • app/(main)/dashboard/page.tsx
  • app/api/analytics/monthly/chart/route.ts
  • app/components/Sidebar.tsx
  • app/components/analytics/AnalyticsChartCard.tsx
  • app/components/analytics/AnalyticsTotalsRow.tsx
  • app/components/analytics/index.ts
  • app/components/icons/index.tsx
  • app/components/icons/sidebar/ChartBarIcon.tsx
  • app/hooks/useAnalyticsChart.ts
  • app/hooks/useAnalyticsTotals.ts
  • app/lib/navConfig.ts
  • app/lib/types/analytics.ts
  • app/lib/utils/analytics/normalizeSeries.ts
  • package.json

Comment thread app/(main)/dashboard/page.tsx Outdated
Comment thread app/api/analytics/monthly/chart/route.ts
Comment thread app/components/analytics/AnalyticsTotalsRow.tsx Outdated
Comment thread app/hooks/useAnalyticsChart.ts Outdated
Comment thread app/hooks/useAnalyticsTotals.ts
@Ayush8923 Ayush8923 requested a review from vprashrex May 26, 2026 05:15
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a 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 (2)
app/lib/constants.ts (1)

104-112: 💤 Low value

Consider adding parameter validation for edge cases.

The count parameter is not validated. While negative or zero values will safely produce an empty array, adding a guard could make the behavior more explicit and prevent unintended usage.

🛡️ Suggested defensive check
 export function getRecentYearOptions(
   count = 2,
 ): { value: string; label: string }[] {
+  if (count <= 0) return [];
   const now = new Date().getFullYear();
   return Array.from({ length: count }, (_, i) => {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/lib/constants.ts` around lines 104 - 112, The getRecentYearOptions
function lacks validation for the count parameter; add a defensive check at the
top of getRecentYearOptions to ensure count is a non-negative integer (e.g.,
coerce with Number.isFinite and Math.floor, then clamp with Math.max(0, ...))
and handle invalid inputs explicitly by either returning an empty array or
throwing a clear TypeError; this makes the behavior explicit for negative,
fractional, or non-numeric values while keeping the rest of the implementation
unchanged.
app/lib/types/analytics.ts (1)

13-19: 💤 Low value

Consider documenting the data: string[] contract.

The data field is typed as string[] rather than number[], which suggests the backend returns numeric values as strings (common for precision preservation). Consider adding a JSDoc comment explaining this contract and that consumers should parse these values.

📝 Suggested documentation
 export interface AnalyticsSeriesPoint {
   name: string;
+  /** Numeric data points returned as strings to preserve precision */
   data: string[];
   total_input_tokens?: number;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/lib/types/analytics.ts` around lines 13 - 19, Add a concise JSDoc above
the AnalyticsSeriesPoint interface explaining that the data property is string[]
because numeric values are serialized as strings for precision/transport, and
that consumers should parse each entry (e.g., Number(value) or a BigNumber
library) before numeric operations; reference the AnalyticsSeriesPoint type and
the data field and also note that total_input_tokens, total_output_tokens, and
total_tokens are optional aggregated token counts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/lib/utils/analytics/formatValue.ts`:
- Around line 20-32: formatCompactMetric currently inserts the negative sign
after the currency symbol (e.g. "$-1.5k"); update the function to compute the
sign separately (e.g. sign = value < 0 ? "-" : "") and use Math.abs(value) (or
the already computed abs) when creating the compact string, then when metric is
in CURRENCY_METRICS prefix the compact string with sign + "$" (or use
parentheses style if you prefer) so negatives render as "-$1.5k" instead of
"$-1.5k"; adjust references inside formatCompactMetric accordingly.

---

Nitpick comments:
In `@app/lib/constants.ts`:
- Around line 104-112: The getRecentYearOptions function lacks validation for
the count parameter; add a defensive check at the top of getRecentYearOptions to
ensure count is a non-negative integer (e.g., coerce with Number.isFinite and
Math.floor, then clamp with Math.max(0, ...)) and handle invalid inputs
explicitly by either returning an empty array or throwing a clear TypeError;
this makes the behavior explicit for negative, fractional, or non-numeric values
while keeping the rest of the implementation unchanged.

In `@app/lib/types/analytics.ts`:
- Around line 13-19: Add a concise JSDoc above the AnalyticsSeriesPoint
interface explaining that the data property is string[] because numeric values
are serialized as strings for precision/transport, and that consumers should
parse each entry (e.g., Number(value) or a BigNumber library) before numeric
operations; reference the AnalyticsSeriesPoint type and the data field and also
note that total_input_tokens, total_output_tokens, and total_tokens are optional
aggregated token counts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8cd31cf6-50d6-4a77-96b5-52665542f7f8

📥 Commits

Reviewing files that changed from the base of the PR and between 48032df and 84dea98.

📒 Files selected for processing (10)
  • app/(main)/dashboard/page.tsx
  • app/components/analytics/AnalyticsChartCard.tsx
  • app/components/analytics/AnalyticsTotalsRow.tsx
  • app/components/analytics/ChartTooltip.tsx
  • app/components/analytics/MonthYearPicker.tsx
  • app/components/analytics/index.ts
  • app/hooks/useAnalyticsTotals.ts
  • app/lib/constants.ts
  • app/lib/types/analytics.ts
  • app/lib/utils/analytics/formatValue.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/components/analytics/index.ts
  • app/hooks/useAnalyticsTotals.ts
  • app/components/analytics/AnalyticsChartCard.tsx

Comment thread app/lib/utils/analytics/formatValue.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/components/analytics/AnalyticsChartCard.tsx (1)

143-153: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix AnalyticsChartCard InfoTooltip copy to match LineTrendChart (and drop dead __range)

  • app/components/analytics/AnalyticsChartCard.tsx InfoTooltip text says the total is a “thick line” and that there’s a “band … between the lowest and highest group”, but LineTrendChart renders the total as a thin dashed line (strokeWidth={1}) and only plots the per-series lines (strokeWidth={2.25})—there’s no band/area.
  • buildRows computes __range, but ChartTooltip filters out __range and LineTrendChart never uses it; remove the unused __range computation (and associated field if appropriate).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/analytics/AnalyticsChartCard.tsx` around lines 143 - 153,
Update AnalyticsChartCard's InfoTooltip text to match actual rendering in
LineTrendChart: change the copy that describes a "thick line" and a "band ...
between the lowest and highest group" to instead describe that per-series lines
are plotted and the total is shown as a thin dashed line (or similar accurate
wording). Also remove the unused __range computation from buildRows and any
associated field output since ChartTooltip filters out __range and
LineTrendChart never uses it; ensure buildRows and any consuming code no longer
emit or expect __range. Reference: InfoTooltip in AnalyticsChartCard,
LineTrendChart, buildRows, ChartTooltip, and the __range field.
🧹 Nitpick comments (3)
app/components/icons/common/TooltipIcon.tsx (1)

1-4: ⚡ Quick win

Move IconProps into a shared type module.

This local prop shape violates the TS/TSX guideline against redefining shared shapes inline. Please import a shared icon prop type from app/lib/types/ instead of declaring IconProps in this component.

As per coding guidelines, "Import shared types from app/lib/types/ and app/lib/models.ts instead of redefining shapes locally in TypeScript/TSX files."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/icons/common/TooltipIcon.tsx` around lines 1 - 4, Remove the
local IconProps interface from TooltipIcon.tsx and replace it with an import of
the shared icon prop type from app/lib/types; specifically, delete the interface
declaration named IconProps and add an import like `IconProps` from the shared
module, then ensure the TooltipIcon component and any references use that
imported IconProps type instead of the locally declared one.
app/(main)/analytics/page.tsx (1)

20-20: 💤 Low value

Typo in exported constant name PROVIDES_OPTIONS.

This should almost certainly be PROVIDERS_OPTIONS. Worth correcting at the source in constants.ts and here while the surface area is still small.

Also applies to: 157-157

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`(main)/analytics/page.tsx at line 20, The exported constant is
misspelled as PROVIDES_OPTIONS; rename it to PROVIDERS_OPTIONS at the source
(constants.ts) and update all usages (e.g., the import in
app/(main)/analytics/page.tsx and any other references) to import and use
PROVIDERS_OPTIONS instead of PROVIDES_OPTIONS so the symbol name is consistent
across the codebase.
app/components/analytics/MonthYearPicker.tsx (1)

84-90: 💤 Low value

Consider closing the popover on Escape.

The dialog only closes via outside mousedown. Keyboard users cannot dismiss it without clicking away. Adding a keydown listener for Escape improves keyboard accessibility for this role="dialog".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/analytics/MonthYearPicker.tsx` around lines 84 - 90, Add an
Escape key handler inside the existing useEffect that watches the popover
container: in addition to the existing mousedown handler, register a "keydown"
listener that checks for e.key === "Escape" (or e.key === "Esc" for broader
support) and calls setOpen(false) when pressed; ensure you attach and remove
this listener in the same useEffect cleanup so containerRef, setOpen and the
dialog role handling (the popover component using containerRef) properly close
for keyboard users.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/components/analytics/MonthYearPicker.tsx`:
- Around line 146-148: The aria-label on the MonthYearPicker dialog currently
uses the optional prop label, which can be undefined and renders "undefined
picker"; update the aria-label logic in the MonthYearPicker component to fall
back to placeholder or a static string (e.g., use (label ?? placeholder ??
"Month and year") + " picker") so the accessible name is never "undefined
picker"; modify the JSX where role="dialog" and aria-label is set to use this
fallback expression and ensure placeholder and label props are referenced (or
defaulted) in the component props/type definitions.

In `@app/lib/navConfig.ts`:
- Around line 59-64: The nav label "Analytics" in the nav item object (name:
"Analytics", route: "/analytics") is inconsistent with the page title
"Dashboard" rendered by the analytics page; make them match by renaming either
the navConfig entry's name to "Dashboard" or updating the page title string to
"Analytics" so the sidebar label and page title are identical (update the name
in the nav item or the title constant/JSX in the analytics page accordingly).

---

Outside diff comments:
In `@app/components/analytics/AnalyticsChartCard.tsx`:
- Around line 143-153: Update AnalyticsChartCard's InfoTooltip text to match
actual rendering in LineTrendChart: change the copy that describes a "thick
line" and a "band ... between the lowest and highest group" to instead describe
that per-series lines are plotted and the total is shown as a thin dashed line
(or similar accurate wording). Also remove the unused __range computation from
buildRows and any associated field output since ChartTooltip filters out __range
and LineTrendChart never uses it; ensure buildRows and any consuming code no
longer emit or expect __range. Reference: InfoTooltip in AnalyticsChartCard,
LineTrendChart, buildRows, ChartTooltip, and the __range field.

---

Nitpick comments:
In `@app/`(main)/analytics/page.tsx:
- Line 20: The exported constant is misspelled as PROVIDES_OPTIONS; rename it to
PROVIDERS_OPTIONS at the source (constants.ts) and update all usages (e.g., the
import in app/(main)/analytics/page.tsx and any other references) to import and
use PROVIDERS_OPTIONS instead of PROVIDES_OPTIONS so the symbol name is
consistent across the codebase.

In `@app/components/analytics/MonthYearPicker.tsx`:
- Around line 84-90: Add an Escape key handler inside the existing useEffect
that watches the popover container: in addition to the existing mousedown
handler, register a "keydown" listener that checks for e.key === "Escape" (or
e.key === "Esc" for broader support) and calls setOpen(false) when pressed;
ensure you attach and remove this listener in the same useEffect cleanup so
containerRef, setOpen and the dialog role handling (the popover component using
containerRef) properly close for keyboard users.

In `@app/components/icons/common/TooltipIcon.tsx`:
- Around line 1-4: Remove the local IconProps interface from TooltipIcon.tsx and
replace it with an import of the shared icon prop type from app/lib/types;
specifically, delete the interface declaration named IconProps and add an import
like `IconProps` from the shared module, then ensure the TooltipIcon component
and any references use that imported IconProps type instead of the locally
declared one.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e0a7b0e3-a83a-4870-a87f-80a37de3de39

📥 Commits

Reviewing files that changed from the base of the PR and between 84dea98 and dc840b8.

📒 Files selected for processing (21)
  • app/(main)/analytics/page.tsx
  • app/components/analytics/AnalyticsChartCard.tsx
  • app/components/analytics/AnalyticsTotalsRow.tsx
  • app/components/analytics/BreakdownPanel.tsx
  • app/components/analytics/LineTrendChart.tsx
  • app/components/analytics/MonthYearPicker.tsx
  • app/components/icons/common/TooltipIcon.tsx
  • app/components/icons/index.tsx
  • app/components/prompt-editor/DiffView.tsx
  • app/components/ui/InfoTooltip.tsx
  • app/components/ui/Select.tsx
  • app/components/ui/index.ts
  • app/globals.css
  • app/hooks/useAnalyticsChart.ts
  • app/lib/constants.ts
  • app/lib/navConfig.ts
  • app/lib/types/analytics.ts
  • app/lib/types/ui.ts
  • app/lib/utils/analytics/formatValue.ts
  • app/lib/utils/analytics/mergeChartData.ts
  • app/lib/utils/selectOptions.ts
💤 Files with no reviewable changes (1)
  • app/components/ui/index.ts
✅ Files skipped from review due to trivial changes (2)
  • app/lib/utils/selectOptions.ts
  • app/components/prompt-editor/DiffView.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • app/components/icons/index.tsx
  • app/lib/utils/analytics/formatValue.ts
  • app/lib/constants.ts
  • app/components/analytics/AnalyticsTotalsRow.tsx

Comment thread app/components/analytics/MonthYearPicker.tsx
Comment thread app/lib/navConfig.ts
@Ayush8923
Copy link
Copy Markdown
Collaborator Author

Merging this PR into main branch.

@Ayush8923 Ayush8923 merged commit 8a29b3e into main Jun 3, 2026
2 checks passed
@Ayush8923 Ayush8923 deleted the feat/dashboard-analytics-page branch June 3, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Analytics Dashboard: Centralized usage tracking

2 participants