Skip to content

Add search bar and summary stats to Pull Requests page#8

Open
dennisimoo wants to merge 1 commit intomainfrom
demo/big-feature
Open

Add search bar and summary stats to Pull Requests page#8
dennisimoo wants to merge 1 commit intomainfrom
demo/big-feature

Conversation

@dennisimoo
Copy link
Owner

@dennisimoo dennisimoo commented Mar 15, 2026

Summary by CodeRabbit

  • New Features
    • Search functionality on PRs page with real-time filtering by contributor username, repository, or PR title for easier discovery
    • Real-time stats toolbar displaying comprehensive metrics: Total PRs, Pending, Claimed, and Average Score
    • Reorganized filter controls into dedicated toolbar with improved layout for better navigation and accessibility

@dennisimoo
Copy link
Owner Author

Hey @dennisimoo, thanks for your contribution!

GitPay has reviewed your pull request. You can claim your SOL reward using the link below — just connect your Solana wallet and you're good to go.

Claim your reward →


Powered by GitPay · Paid out on Solana

@coderabbitai
Copy link

coderabbitai bot commented Mar 15, 2026

📝 Walkthrough

Walkthrough

Adds search functionality and a real-time statistics toolbar to the PRs page. The new search feature matches contributor usernames, repositories, and PR titles, while a dedicated Stats row displays total PRs, pending count, claimed count, and average score. Filter buttons are consolidated into a toolbar alongside the search input.

Changes

Cohort / File(s) Summary
Search & Stats Integration
src/app/(app)/prs/page.tsx
Introduces search input field with filtering logic against contributor username, repository, and PR title. Adds Stats row displaying Total PRs, Pending, Claimed, and Avg Score metrics. Consolidates filter buttons into dedicated Toolbar component. Implements avgScore computation from all claims and displays contextual no-results message when search is active.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Hop, hop, horay! The PRs now gleam,
With search so quick and stats supreme,
A toolbar shiny, stats so bright,
Average scores and filters right—
The burrow's code just got its shine! ✨

🚥 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 and concisely summarizes the main changes: adding a search bar and summary stats to the Pull Requests page, which matches the AI-generated summary.

✏️ 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 demo/big-feature
📝 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.

Copy link

@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

🧹 Nitpick comments (1)
src/app/(app)/prs/page.tsx (1)

165-179: Consider memoizing derived stats.

The pending and claimed counts are recalculated on every render. For large claim lists, this could be optimized using useMemo:

♻️ Optional optimization
+ const stats = useMemo(() => ({
+   total: claims.length,
+   pending: claims.filter(c => !c.claimed).length,
+   claimed: claims.filter(c => c.claimed).length,
+   avgScore: claims.length ? Math.round(claims.reduce((s, c) => s + c.score, 0) / claims.length) : 0,
+ }), [claims]);

Then reference stats.total, stats.pending, etc. in the JSX.

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

In `@src/app/`(app)/prs/page.tsx around lines 165 - 179, The
pending/claimed/total/avgScore calculations are recomputed each render from
claims; wrap the derived stats in a useMemo hook (e.g., const stats = useMemo(()
=> { total: claims.length, pending: claims.filter(...).length, claimed: ...,
avgScore: ... }, [claims])) and then replace uses of claims.length,
claims.filter(...).length, and avgScore in the JSX with stats.total,
stats.pending, stats.claimed, and stats.avgScore respectively; ensure you import
useMemo from React and keep the same keys used in the mapped array for
rendering.
🤖 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/app/`(app)/prs/page.tsx:
- Around line 197-205: The search input currently uses only a placeholder for
context (the <input> with value={search} and onChange={(e) =>
setSearch(e.target.value)}), which is not reliably announced by screen readers;
add an accessible label by adding an aria-label attribute (e.g.,
aria-label="Search PRs by contributor, repo, or title") to the same <input>
element so assistive technologies get explicit context while preserving the
existing placeholder and behavior.
- Around line 209-213: The empty-state message currently only checks filtered
and search; update the JSX where filtered and search are used to also consider
the active filter state (e.g., selectedFilter / statusFilter / filters) so the
message reflects whether there are no results because of a search, an active
filter, or truly no PRs; change the conditional that renders the <div> to
branch: if filtered.length === 0 and search show "No results matched your
search", else if filtered.length === 0 and a filter is active show "No pull
requests match the selected filter" (ideally including the filter name),
otherwise show "No pull requests yet". Use the existing symbols filtered and
search and the app's filter state variable to locate and implement the logic in
page.tsx.

---

Nitpick comments:
In `@src/app/`(app)/prs/page.tsx:
- Around line 165-179: The pending/claimed/total/avgScore calculations are
recomputed each render from claims; wrap the derived stats in a useMemo hook
(e.g., const stats = useMemo(() => { total: claims.length, pending:
claims.filter(...).length, claimed: ..., avgScore: ... }, [claims])) and then
replace uses of claims.length, claims.filter(...).length, and avgScore in the
JSX with stats.total, stats.pending, stats.claimed, and stats.avgScore
respectively; ensure you import useMemo from React and keep the same keys used
in the mapped array for rendering.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c93ef42b-de91-4cab-b993-f1fb4aab589d

📥 Commits

Reviewing files that changed from the base of the PR and between 00f078f and 52c98c3.

📒 Files selected for processing (1)
  • src/app/(app)/prs/page.tsx

Comment on lines +197 to +205
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search by contributor, repo, or title…"
style={{
flex: 1, padding: "6px 12px", border: "1px solid #e4e4e7", borderRadius: "7px",
fontSize: "12px", fontFamily: "inherit", color: "#000", outline: "none", background: "#fff",
}}
/>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add aria-label for accessibility.

The search input relies solely on placeholder for context, which is not announced by all screen readers. Adding an aria-label improves accessibility.

♿ Proposed fix
           <input
             value={search}
             onChange={(e) => setSearch(e.target.value)}
             placeholder="Search by contributor, repo, or title…"
+            aria-label="Search pull requests"
             style={{
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search by contributor, repo, or title…"
style={{
flex: 1, padding: "6px 12px", border: "1px solid #e4e4e7", borderRadius: "7px",
fontSize: "12px", fontFamily: "inherit", color: "#000", outline: "none", background: "#fff",
}}
/>
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search by contributor, repo, or title…"
aria-label="Search pull requests"
style={{
flex: 1, padding: "6px 12px", border: "1px solid `#e4e4e7`", borderRadius: "7px",
fontSize: "12px", fontFamily: "inherit", color: "#000", outline: "none", background: "#fff",
}}
/>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`(app)/prs/page.tsx around lines 197 - 205, The search input
currently uses only a placeholder for context (the <input> with value={search}
and onChange={(e) => setSearch(e.target.value)}), which is not reliably
announced by screen readers; add an accessible label by adding an aria-label
attribute (e.g., aria-label="Search PRs by contributor, repo, or title") to the
same <input> element so assistive technologies get explicit context while
preserving the existing placeholder and behavior.

Comment on lines 209 to 213
{filtered.length === 0 ? (
<div style={{ border: "1px dashed #e4e4e7", borderRadius: "12px", padding: "48px 24px", textAlign: "center" }}>
<GitMerge size={28} strokeWidth={1.5} color="#d4d4d8" style={{ display: "inline-block", marginBottom: "10px" }} />
<p style={{ fontSize: "14px", color: "#71717a" }}>No pull requests yet</p>
<p style={{ fontSize: "14px", color: "#71717a" }}>{search ? "No results matched your search" : "No pull requests yet"}</p>
</div>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider filter state in the empty message.

The message distinguishes between search and no-data, but doesn't account for filter state. If a user filters to "claimed" but all PRs are pending, they see "No pull requests yet" which is misleading since PRs exist.

💡 Suggested improvement
-              <p style={{ fontSize: "14px", color: "#71717a" }}>{search ? "No results matched your search" : "No pull requests yet"}</p>
+              <p style={{ fontSize: "14px", color: "#71717a" }}>
+                {search || filter !== "all"
+                  ? "No results matched your filters"
+                  : "No pull requests yet"}
+              </p>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{filtered.length === 0 ? (
<div style={{ border: "1px dashed #e4e4e7", borderRadius: "12px", padding: "48px 24px", textAlign: "center" }}>
<GitMerge size={28} strokeWidth={1.5} color="#d4d4d8" style={{ display: "inline-block", marginBottom: "10px" }} />
<p style={{ fontSize: "14px", color: "#71717a" }}>No pull requests yet</p>
<p style={{ fontSize: "14px", color: "#71717a" }}>{search ? "No results matched your search" : "No pull requests yet"}</p>
</div>
{filtered.length === 0 ? (
<div style={{ border: "1px dashed `#e4e4e7`", borderRadius: "12px", padding: "48px 24px", textAlign: "center" }}>
<GitMerge size={28} strokeWidth={1.5} color="#d4d4d8" style={{ display: "inline-block", marginBottom: "10px" }} />
<p style={{ fontSize: "14px", color: "#71717a" }}>
{search || filter !== "all"
? "No results matched your filters"
: "No pull requests yet"}
</p>
</div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`(app)/prs/page.tsx around lines 209 - 213, The empty-state message
currently only checks filtered and search; update the JSX where filtered and
search are used to also consider the active filter state (e.g., selectedFilter /
statusFilter / filters) so the message reflects whether there are no results
because of a search, an active filter, or truly no PRs; change the conditional
that renders the <div> to branch: if filtered.length === 0 and search show "No
results matched your search", else if filtered.length === 0 and a filter is
active show "No pull requests match the selected filter" (ideally including the
filter name), otherwise show "No pull requests yet". Use the existing symbols
filtered and search and the app's filter state variable to locate and implement
the logic in page.tsx.

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