Skip to content

feat: improve dashboard chart interactions#379

Closed
KMKoushik wants to merge 4 commits intomainfrom
better-ui
Closed

feat: improve dashboard chart interactions#379
KMKoushik wants to merge 4 commits intomainfrom
better-ui

Conversation

@KMKoushik
Copy link
Member

@KMKoushik KMKoushik commented Mar 15, 2026

Summary

  • improve dashboard chart interaction behavior so metric chips control visible series while keeping total as display-only
  • refine dashboard chart presentation (axis text treatment and bar sizing) for readability
  • keep analytics range controls aligned with a 30-day default while preserving the 7/30 day toggle

Verification

  • pnpm --filter web build

Summary by cubic

Make the dashboard email chart interactive and easier to read. Metric chips now toggle visible series (total is display-only), and the analytics default range is 30 days.

  • New Features
    • Click metric chips to show/hide stacked series; tooltip and bars reflect selected metrics.
    • Total metric chip is non-clickable and always display-only.
    • Default analytics range set to 30 days; 7/30 toggle remains.
    • Larger bar size and cleaner X-axis (no axis/tick lines) for readability.
    • Updated sidebar color tokens for better contrast in light/dark themes.

Written for commit 9dd0ead. Summary will update on new commits.

Summary by CodeRabbit

Release Notes

  • New Features

    • Email chart metrics are now interactive—click individual metrics (delivered, bounced, etc.) to toggle their visibility and focus on relevant data
    • Active metric indicators provide visual feedback on selected metrics
  • Style

    • Updated sidebar color scheme for improved visual appearance
  • Chores

    • Changed default dashboard time period to 30 days

@vercel
Copy link

vercel bot commented Mar 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
unsend-marketing Ready Ready Preview, Comment Mar 15, 2026 1:04pm

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 15, 2026

Walkthrough

This pull request updates the default dashboard time period from 7 days to 30 days across multiple components and introduces metric visibility toggling functionality to the email chart. The createRoundedTopShape function is refactored to accept a visibleStackOrder parameter for dynamic stack ordering. The DashboardItemCardProps interface is extended with interactivity properties (onClick, isActive, isClickable). Sidebar color tokens are updated in the global stylesheet for both light and dark themes. Minor formatting adjustments are made to the dashboard service file.

Possibly related PRs

  • PR #206: Modifies email-chart.tsx for chart color handling, overlapping with this PR's metric rendering refactoring
  • PR #320: Modifies email-chart.tsx tooltip and data handling, related to this PR's refactored tooltip aggregation using visibleMetrics

Suggested labels

codex

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adding metric chip interactivity to dashboard charts with visibility controls.

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

📝 Coding Plan
  • Generate coding plan for human review comments

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.

@cloudflare-workers-and-pages
Copy link

Deploying usesend with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9dd0ead
Status: ✅  Deploy successful!
Preview URL: https://a7409502.usesend.pages.dev
Branch Preview URL: https://better-ui.usesend.pages.dev

View logs

Copy link
Contributor

@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

Caution

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

⚠️ Outside diff range comments (1)
apps/web/src/app/(dashboard)/dashboard/page.tsx (1)

10-28: ⚠️ Potential issue | 🟠 Major

Normalize URL days before numeric conversion.

On Line 26 and Line 28, Number(days ?? "30") can pass NaN or unsupported values when days is manually set in the URL (e.g., ?days=foo, ?days=90). Normalize once to "7" | "30" and reuse that value across filters and charts.

Suggested fix
 export default function Dashboard() {
   const [days, setDays] = useUrlState("days", "30");
   const [domain, setDomain] = useUrlState("domain");
+  const normalizedDays = days === "7" || days === "30" ? days : "30";
+  const numericDays = Number(normalizedDays);

   return (
     <div>
       <div className="w-full">
         <div className="flex justify-between items-center mb-10">
           <H1>Analytics</H1>
           <DashboardFilters
-            days={days ?? "30"}
+            days={normalizedDays}
             setDays={setDays}
             domain={domain}
             setDomain={setDomain}
           />
         </div>
         <div className=" space-y-12">
-          <EmailChart days={Number(days ?? "30")} domain={domain} />
+          <EmailChart days={numericDays} domain={domain} />

-          <ReputationMetrics days={Number(days ?? "30")} domain={domain} />
+          <ReputationMetrics days={numericDays} domain={domain} />
         </div>
       </div>
     </div>
   );
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/app/`(dashboard)/dashboard/page.tsx around lines 10 - 28,
Normalize the URL-derived days value once before numeric conversion and pass the
normalized value into filters and charts: validate the `days` from
`useUrlState("days", "30")`, coerce it to either "7" or "30" (default to "30"
for invalid values), update `setDays` usage accordingly, and replace all
occurrences of `Number(days ?? "30")` (used when rendering `DashboardFilters`,
`EmailChart`, and `ReputationMetrics`) with the single normalized value (and
numeric conversion only where the components expect a number) so charts never
receive NaN or unsupported values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/server/service/dashboard-service.ts`:
- Around line 12-15: The date-range logic currently produces one extra day
because it both sets startDate to "now - days" and then fills an inclusive
range; fix by making the days selection explicit and adjusting the start offset:
set days = input.days === 7 ? 7 : 30 (instead of input.days !== 7 ? 30 : 7) and
compute startDate by subtracting days - 1 (startDate.setDate(startDate.getDate()
- (days - 1))) so the inclusive fill loop (the code that iterates from startDate
to today to produce points) yields exactly `days` points; also review the fill
loop that iterates from startDate to endDate to ensure it treats both ends
consistently with this change.

---

Outside diff comments:
In `@apps/web/src/app/`(dashboard)/dashboard/page.tsx:
- Around line 10-28: Normalize the URL-derived days value once before numeric
conversion and pass the normalized value into filters and charts: validate the
`days` from `useUrlState("days", "30")`, coerce it to either "7" or "30"
(default to "30" for invalid values), update `setDays` usage accordingly, and
replace all occurrences of `Number(days ?? "30")` (used when rendering
`DashboardFilters`, `EmailChart`, and `ReputationMetrics`) with the single
normalized value (and numeric conversion only where the components expect a
number) so charts never receive NaN or unsupported values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 421e6142-7115-4569-8b94-7b83d3c6c4c1

📥 Commits

Reviewing files that changed from the base of the PR and between 4307670 and 9dd0ead.

📒 Files selected for processing (5)
  • apps/web/src/app/(dashboard)/dashboard/dashboard-filters.tsx
  • apps/web/src/app/(dashboard)/dashboard/email-chart.tsx
  • apps/web/src/app/(dashboard)/dashboard/page.tsx
  • apps/web/src/server/service/dashboard-service.ts
  • packages/ui/styles/globals.css

Comment on lines +12 to 15
const days = input.days !== 7 ? 30 : 7;
const { domain, team } = input;
const startDate = new Date();
startDate.setDate(startDate.getDate() - days);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix off-by-one range calculation for 7/30 day windows.

Line 12 currently drives an inclusive range that returns 8 points for 7 and 31 points for 30 (startDate includes the start day, and the fill loop also includes both ends). This breaks the stated 7/30-day toggle semantics.

Proposed fix
 export async function emailTimeSeries(input: EmailTimeSeries) {
-  const days = input.days !== 7 ? 30 : 7;
+  const days = input.days === 7 ? 7 : 30;
   const { domain, team } = input;
   const startDate = new Date();
-  startDate.setDate(startDate.getDate() - days);
+  startDate.setDate(startDate.getDate() - (days - 1));
-  for (let i = days; i > -1; i--) {
+  for (let i = days - 1; i >= 0; i--) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/server/service/dashboard-service.ts` around lines 12 - 15, The
date-range logic currently produces one extra day because it both sets startDate
to "now - days" and then fills an inclusive range; fix by making the days
selection explicit and adjusting the start offset: set days = input.days === 7 ?
7 : 30 (instead of input.days !== 7 ? 30 : 7) and compute startDate by
subtracting days - 1 (startDate.setDate(startDate.getDate() - (days - 1))) so
the inclusive fill loop (the code that iterates from startDate to today to
produce points) yields exactly `days` points; also review the fill loop that
iterates from startDate to endDate to ensure it treats both ends consistently
with this change.

@KMKoushik KMKoushik closed this Mar 15, 2026
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