Skip to content

fix: full-graph new users render green + debounce topNodes slider#1721

Merged
Hugo0 merged 2 commits intomainfrom
fix/full-graph-new-users
Mar 10, 2026
Merged

fix: full-graph new users render green + debounce topNodes slider#1721
Hugo0 merged 2 commits intomainfrom
fix/full-graph-new-users

Conversation

@Hugo0
Copy link
Copy Markdown
Contributor

@Hugo0 Hugo0 commented Mar 10, 2026

Summary

  • Green new users: Changed new user node color from blue (rgba(144, 168, 237)) to green (rgba(74, 222, 128)) to match the existing legend which already shows green for "New"
  • Debounced topNodes slider: Slider no longer triggers API refetch on every tick — debounced by 500ms so you can drag freely
  • Always show new users: Passes includeNewDays param to backend so new users appear in the graph regardless of topNodes point ranking

Safety

  • Payment graph: Unaffected — payment mode returns 'active' for all nodes, never hits the green color path
  • User invite graph (points page): Unaffected — uses minimal mode (all-pink) and different API endpoint (getUserInvitesGraph)
  • Color change only applies to full-graph with activity filter enabled

Companion PR

Backend: peanutprotocol/peanut-api-ts — fix/graph-createdAt-null-safety (adds includeNewDays backend support + null safety)

Test plan

  • Open /dev/full-graph, verify new users (within activity window) show as green circles
  • Verify legend matches (green dot = New)
  • Drag the topNodes slider — should not spam-reload, only fetches after stopping
  • Set topNodes to a low number — new users should still appear
  • Check /dev/payment-graph still works normally (no green nodes)
  • Check points page invite graph still works (all pink nodes)

Note

Medium Risk
Touches graph data fetching cadence and the invites-graph API query contract (includeNewDays), which could affect load behavior if the backend handling differs; UI-only color change is low risk.

Overview
Improves the full invites graph fetch behavior by debouncing topNodes-driven refetches (500ms) to avoid API spam while dragging the slider.

Extends pointsApi.getInvitesGraph and the graph request to send a new includeNewDays query param so recent signups remain included even when topNodes limits results, and updates the activity-filter rendering so "new" users render green instead of blue.

Written by Cursor Bugbot for commit 3d42b95. This will update automatically on new commits. Configure here.

- Change new user node color from blue to green to match legend
- Debounce topNodes slider (500ms) to prevent refetch on every tick
- Pass includeNewDays to backend so new users always appear regardless of topNodes filter
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 10, 2026

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

Project Deployment Actions Updated (UTC)
peanut-wallet Ready Ready Preview, Comment Mar 10, 2026 2:38pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8952e3f3-d92c-40f6-910a-0a80432741a6

📥 Commits

Reviewing files that changed from the base of the PR and between fcd0aa6 and 3d42b95.

📒 Files selected for processing (1)
  • src/components/Global/InvitesGraph/index.tsx

Walkthrough

Debounced subsequent fetches were added to InvitesGraph (first fetch remains immediate); the component now passes an includeNewDays parameter to the invites graph API; node color for "new" activity changed to green; getInvitesGraph signature and query-building were updated to accept includeNewDays.

Changes

Cohort / File(s) Summary
Component: Invites graph behavior & visuals
src/components/Global/InvitesGraph/index.tsx
Added debounce refs (topNodesDebounceRef, isInitialFetchRef) to debounce subsequent topNodes-based fetches (500ms) after the initial immediate fetch; wired includeNewDays (from activityFilter.activityDays) into API call; changed "new" node fill color to rgba(74, 222, 128, 0.85); ensure debounce timer cleanup on unmount.
Service: API parameter support
src/services/points.ts
Extended getInvitesGraph options to include includeNewDays?: number; when includeNewDays > 0 add it to the /invites/graph query parameters; preserved existing auth/endpoint logic.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

🚥 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
Title check ✅ Passed The title accurately summarizes the two main changes: green color for new users and debounced topNodes slider, matching the core objectives.
Description check ✅ Passed The pull request description clearly relates to the changeset, detailing the three main changes: green node color for new users, debounced topNodes slider, and includeNewDays parameter addition.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/full-graph-new-users

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

Copy link
Copy Markdown
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

🧹 Nitpick comments (1)
src/components/Global/InvitesGraph/index.tsx (1)

1136-1138: Extract the new-user fill color into shared graph constants.

This PR fixes a legend mismatch with another inline RGBA literal, so the legend and node fill can drift again on the next palette tweak. Reuse a shared constant for both surfaces instead of hardcoding the value here.

As per coding guidelines, "Follow DRY (Don't Repeat Yourself) - reuse existing code and abstract shared functionality; use shared consts from src/constants".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/Global/InvitesGraph/index.tsx` around lines 1136 - 1138,
Replace the hardcoded RGBA literal used when activityStatus === 'new' (where
fillColor is set) with a shared constant exported from the shared constants
module (create/export NEW_USER_FILL_COLOR or GRAPH_NEW_NODE_FILL there); update
the import in this component and any legend code to reference that same exported
constant so both node fill and legend reuse the identical value instead of
duplicating the literal (search for activityStatus, fillColor, and the legend
rendering to change usages).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/Global/InvitesGraph/index.tsx`:
- Around line 858-863: The effect that calls pointsApi.getInvitesGraph (passing
includeNewDays: activityFilter.activityDays) only depends on
apiKey/mode/topNodes so changes to activityFilter.activityDays don't trigger a
refetch; update the useEffect dependency arrays that invoke getInvitesGraph
(references: getInvitesGraph, includeNewDays, pointsApi, topNodes, apiKey, mode,
password) to include activityFilter.activityDays so the graph is refetched
whenever the activity window changes (apply the same change to the other similar
effect block that covers lines 874-887).

---

Nitpick comments:
In `@src/components/Global/InvitesGraph/index.tsx`:
- Around line 1136-1138: Replace the hardcoded RGBA literal used when
activityStatus === 'new' (where fillColor is set) with a shared constant
exported from the shared constants module (create/export NEW_USER_FILL_COLOR or
GRAPH_NEW_NODE_FILL there); update the import in this component and any legend
code to reference that same exported constant so both node fill and legend reuse
the identical value instead of duplicating the literal (search for
activityStatus, fillColor, and the legend rendering to change usages).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 54643109-4876-448c-92cf-6a58bb1a806d

📥 Commits

Reviewing files that changed from the base of the PR and between 241e2ca and fcd0aa6.

📒 Files selected for processing (2)
  • src/components/Global/InvitesGraph/index.tsx
  • src/services/points.ts

Comment on lines +858 to 863
// Pass includeNewDays so backend always includes recent signups regardless of topNodes
const result = await pointsApi.getInvitesGraph(props.apiKey, {
mode: apiMode,
topNodes: topNodes > 0 ? topNodes : undefined,
includeNewDays: activityFilter.activityDays,
password: mode === 'payment' ? props.password : undefined,
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.

⚠️ Potential issue | 🟠 Major

Refetch when the activity window changes.

includeNewDays now comes from activityFilter.activityDays, but this effect still only re-runs for apiKey/mode/topNodes. With topNodes > 0, a saved non-default activity window—or changing the window after mount—keeps the request pinned to the old includeNewDays, so some "new" users never get fetched until topNodes changes.

🛠️ Minimal fix
-    }, [isMinimal, !isMinimal && props.apiKey, mode, topNodes])
+    }, [isMinimal, !isMinimal && props.apiKey, mode, topNodes, activityFilter.activityDays])

Also applies to: 874-887

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/Global/InvitesGraph/index.tsx` around lines 858 - 863, The
effect that calls pointsApi.getInvitesGraph (passing includeNewDays:
activityFilter.activityDays) only depends on apiKey/mode/topNodes so changes to
activityFilter.activityDays don't trigger a refetch; update the useEffect
dependency arrays that invoke getInvitesGraph (references: getInvitesGraph,
includeNewDays, pointsApi, topNodes, apiKey, mode, password) to include
activityFilter.activityDays so the graph is refetched whenever the activity
window changes (apply the same change to the other similar effect block that
covers lines 874-887).

Use displaySettingsRef to read current activityFilter.activityDays
so includeNewDays always reflects the latest value without adding
activityFilter to the useEffect dependency array.
@Hugo0 Hugo0 force-pushed the fix/full-graph-new-users branch from fef756c to 3d42b95 Compare March 10, 2026 14:31
@Hugo0 Hugo0 merged commit efa9424 into main Mar 10, 2026
7 of 8 checks passed
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

} else {
if (topNodesDebounceRef.current) clearTimeout(topNodesDebounceRef.current)
topNodesDebounceRef.current = setTimeout(fetchData, 500)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Debounce applies to all dependency changes, not just topNodes

Low Severity

The isInitialFetchRef gate applies the 500ms debounce to every dependency change (mode, apiKey, isMinimal, topNodes) after the first fetch, but the intent is to debounce only topNodes slider drags. If mode or apiKey ever changed at runtime, the fetch would be needlessly delayed by 500ms. With current call sites these props are effectively constant, so the bug is latent, but the logic doesn't match the stated intent in the comment on line 874.

Fix in Cursor Fix in Web

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