Skip to content

refactor(credits-page): standardized styling and added pagination - #217

Merged
Ryan-Millard merged 15 commits into
Ryan-Millard:mainfrom
laxitajain:fix/grammar-on-credits
Jan 26, 2026
Merged

refactor(credits-page): standardized styling and added pagination #217
Ryan-Millard merged 15 commits into
Ryan-Millard:mainfrom
laxitajain:fix/grammar-on-credits

Conversation

@laxitajain

@laxitajain laxitajain commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

⚠️ Are you using the correct pull request template?
Please choose one of the following:

If none of these fit, you may use this default to describe your change manually.

If this is the right template, go ahead and complete it below 👇


📌 Description

Currently, in the Contributors section on the Credits page, the plural “commits” is used even for a single commit. While I understand that a full rework of the Credits page is needed, this PR fixes the grammatical issue for the time being.

Issue

Fixes #218

✅ Type of Change

Place an "x" in the brackets below:

  • Bug fix 🐛
  • New feature ✨
  • Refactor 🔧
  • Documentation 📚
  • Build/dependency update 🧱
  • Other (describe): (grammar fix)

🧪 How Has This Been Tested?

Please describe how you tested your changes (e.g., unit tests, manual testing, screenshots, etc.)

🧩 Checklist

Place an "x" in the brackets below:

  • I’ve followed the contribution guidelines.
  • My code follows the code style of this project.
  • I’ve added tests where necessary.
  • I’ve updated the documentation where applicable.
  • I’ve linked related issues or discussions (if any).
  • I’ve checked for breaking changes and backwards compatibility.

📸 Screenshots / Demo (if applicable)

Paste images, GIFs, or demo links here.

💬 Additional Context

Anything else relevant to the PR.

Summary by CodeRabbit

  • New Features
    • Added client-side pagination with keyboard-friendly, accessible controls for contributor and dependency credits; per-page view limits set to 10.
  • Style
    • Tighter spacing and layout updates on Credits pages; new responsive pagination and table styling for mobile and desktop.
  • Content
    • Minor text adjustments (singular/plural "commit") and clearer link/URL presentation in static and dependency credits.
  • Documentation
    • Added Pagination docs and usage guide.
  • Tests
    • Added comprehensive tests for the Pagination component.

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

@coderabbitai

coderabbitai Bot commented Jan 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a reusable Pagination component with keyboard navigation and integrates client-side pagination (PAGE_SIZE=10) into Contributors and Dependency credits tables; introduces responsive table CSS modules and minor static-table structural/styling tweaks.

Changes

Cohort / File(s) Summary
Pagination component
src/components/Pagination.jsx, src/components/Pagination.module.css, docs/docs/reference/react/components/Pagination/*, src/components/Pagination.test.jsx
New accessible Pagination export with visible-page calculation, prev/next/first/last buttons, ellipses, ArrowLeft/ArrowRight keyboard handlers (ignores form fields), ARIA attributes, responsive styles, docs, tests, and hidden when totalPages <= 1. Review keyboard handler cleanup and test coverage.
Contributors card (pagination)
src/pages/Credits/ContributorsCreditsCard.jsx
Added useState page state and Pagination usage; per-page chunk size changed from 13 to 10; renders only active contributor chunk; singular/plural "commit" text logic added. Check rendering of tooltips/avatars and page indexing.
Dependency credits (pagination + table styles)
src/pages/Credits/DependencyCreditsCard.jsx, src/pages/Credits/DependencyCreditsCard.module.css
Adds per-section pagination (depPage, devDepPage, PAGE_SIZE=10), paginated indexing for rows, URL cell improvements (tooltip, external icon, loading/no-URL states), new responsive .table styles, and Pagination controls per card. Verify URL rendering and index calculation.
Static credits table styling & markup
src/pages/Credits/StaticCreditsCard.jsx, src/pages/Credits/StaticCreditsCard.module.css
Applies CSS module to static table, restructures some table cells (merged content and punctuation adjustments), and enforces centering/no-wrap on first cell.
Credits page container styling
src/pages/Credits/Credits.module.css
Reduced vertical gap (2rem → 1rem) and removed max-width constraint; purely styling change.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Pagination
  participant CreditsCard
  participant DataSource

  User->>Pagination: click page button / press Arrow key
  Pagination->>CreditsCard: onChange(newPage)
  CreditsCard->>CreditsCard: compute start = page * PAGE_SIZE
  CreditsCard->>DataSource: request/render rows for start..start+PAGE_SIZE-1
  CreditsCard->>User: render table rows for current page
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

refactor, ux

Suggested reviewers

  • Ryan-Millard

Poem

I nibble through lists, ten at a time,
arrows and dots make pages align,
a hop to the next, a gentle click,
rows neaten up—my joy’s quick!
— rabbit reviewer 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: refactoring Credits page styling and adding pagination. It is concise and clearly reflects the core objectives of the PR.
Linked Issues check ✅ Passed The PR implements all primary requirements from issue #218: standardized styling across Credits cards via CSS modules, added pagination to dynamic tables (Contributors, Dependencies, Dev Dependencies), and included responsive design for smaller screens.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #218 objectives. The PR includes a new Pagination component, CSS styling modules, documentation, tests, and integrations into three data tables—all aligned with the stated refactor scope.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@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

🤖 Fix all issues with AI agents
In @src/pages/Credits/ContributorsCreditsCard.jsx:
- Around line 48-50: Update the pluralization check for contributor counts in
the ContributorsCreditsCard rendering: replace the current conditional that uses
c.contributions > 1 with a check for exactly one (c.contributions === 1) so that
only a single contribution renders "commit" and all other values (including 0)
render "commits"; make this change where the JSX outputs "{c.contributions} ..."
for variable c.contributions.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d933d0 and 0e02196.

📒 Files selected for processing (1)
  • src/pages/Credits/ContributorsCreditsCard.jsx

Comment thread src/pages/Credits/ContributorsCreditsCard.jsx Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@Ryan-Millard

Copy link
Copy Markdown
Owner

Hi @laxitajain. Thank you for this change - it is worth having.

Since this is such a small PR and I intended to create an issue for a full refactor of this page, would you be interested in updating this PR to do that? It involves ensuring that the styles on the credits page are consistent with the rest of the pages and adding pagination to the tables (since they've grown a lot since the creation of the page and dynamic fetches can be slow).

Below is the main problem, the GlassCard containers aren't the same size as they are on the other pages:
image

image

@laxitajain

Copy link
Copy Markdown
Contributor Author

sure, will be working on this refactor then!

@Ryan-Millard

Copy link
Copy Markdown
Owner

sure, will be working on this refactor then!

Great. I'll create an issue for it now. You can start work on it so long if you'd like - I've already explained the basics.

@Ryan-Millard

Copy link
Copy Markdown
Owner

@laxitajain, I just added #218 - comment /take on it if you'd like to work on it.

@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

🤖 Fix all issues with AI agents
In @src/components/Pagination.jsx:
- Around line 18-30: The global keydown handler in the Pagination component's
useEffect (handler) acts on ArrowLeft/ArrowRight without checking the event
target, which breaks arrow key usage inside inputs/textareas/contenteditable
elements; update handler to ignore events when the active/target element is an
input, textarea, select, or has isContentEditable true (or when an element with
role textbox is focused) before running onChange(page ± 1), keeping the existing
page, totalPages and onChange logic intact.

In @src/pages/Credits/ContributorsCreditsCard.jsx:
- Line 1: The import statement in ContributorsCreditsCard.jsx imports useEffect
but it is unused; update the React import to remove useEffect (keep useState) so
the import reads only the hooks actually used, ensuring no other references to
useEffect remain in the ContributorsCreditsCard component.
- Line 54: The cell currently hardcodes "commits" causing incorrect grammar for
a single contribution; update the rendering in ContributorsCreditsCard.jsx to
conditionally use "commit" vs "commits" based on c.contributions (e.g.,
c.contributions === 1 ? 'commit' : 'commits') or extract a small helper like
formatContributions(contributions) that returns the correctly pluralized string
and use it where the JSX presently renders "<td>{c.contributions} commits</td>".
🧹 Nitpick comments (3)
src/pages/Credits/StaticCreditsCard.jsx (1)

43-43: Fix inconsistent spacing around the dash.

"Pixel Art Hedgehog- By" has the dash attached to "Hedgehog" with no space before it, but a space after the dash before "By". This creates inconsistent visual spacing.

✨ Proposed fix for consistent spacing
-              Pixel Art Hedgehog- By{' '}
+              Pixel Art Hedgehog - By{' '}

This provides balanced spacing on both sides of the dash separator.

src/components/Pagination.jsx (1)

18-30: Consider documenting onChange stability requirement.

The onChange callback is included in the useEffect dependency array. If parent components don't provide a stable reference (e.g., passing an inline arrow function), the keyboard listener will be removed and re-added on every render.

Current usage in this PR passes setState functions directly, which are stable. However, for future maintainability, consider adding a JSDoc comment documenting that onChange should be a stable reference.

📝 Optional: Add JSDoc to document prop requirements
+/**
+ * Pagination component with keyboard navigation support.
+ * @param {Object} props
+ * @param {number} props.page - Current page index (0-based)
+ * @param {number} props.totalPages - Total number of pages
+ * @param {Function} props.onChange - Callback when page changes (should be stable/memoized)
+ */
 export default function Pagination({ page, totalPages, onChange }) {
src/pages/Credits/DependencyCreditsCard.module.css (1)

4-4: Remove !important declarations and resolve specificity conflicts.

The !important flags on width properties indicate specificity issues. CSS modules already provide scoping, so these shouldn't be necessary. Using !important makes the styles harder to maintain and debug.

🧹 Suggested approach to resolve
  1. Remove the !important declarations
  2. If styles don't apply correctly, investigate competing styles:
    • Check for global table styles
    • Check if parent components (like GlassCard) override table widths
    • Use browser DevTools to identify which styles are conflicting
 .table {
   margin-left: auto;
   margin-right: auto;
-  width: 80% !important;
+  width: 80%;
   min-width: 80%;
   table-layout: fixed;
 }

 @media (max-width: 600px) {
   .table {
-    width: 100% !important;
+    width: 100%;
     min-width: 100%;
     table-layout: fixed;
   }

Also applies to: 44-44

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9b328a and 788aa44.

📒 Files selected for processing (8)
  • src/components/Pagination.jsx
  • src/components/Pagination.module.css
  • src/pages/Credits/ContributorsCreditsCard.jsx
  • src/pages/Credits/Credits.module.css
  • src/pages/Credits/DependencyCreditsCard.jsx
  • src/pages/Credits/DependencyCreditsCard.module.css
  • src/pages/Credits/StaticCreditsCard.jsx
  • src/pages/Credits/StaticCreditsCard.module.css
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 217
File: src/pages/Credits/ContributorsCreditsCard.jsx:48-50
Timestamp: 2026-01-09T14:45:56.443Z
Learning: In src/pages/Credits/ContributorsCreditsCard.jsx, the contributor data comes from GitHub's /contributors API endpoint (via scripts/generate-contributor-credits-json.js), which only returns contributors with at least one contribution. Therefore, c.contributions will always be >= 1 and the zero case is impossible.
📚 Learning: 2026-01-09T14:45:56.443Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 217
File: src/pages/Credits/ContributorsCreditsCard.jsx:48-50
Timestamp: 2026-01-09T14:45:56.443Z
Learning: In src/pages/Credits/ContributorsCreditsCard.jsx, the contributor data comes from GitHub's /contributors API endpoint (via scripts/generate-contributor-credits-json.js), which only returns contributors with at least one contribution. Therefore, c.contributions will always be >= 1 and the zero case is impossible.

Applied to files:

  • src/pages/Credits/DependencyCreditsCard.jsx
  • src/pages/Credits/StaticCreditsCard.jsx
  • src/pages/Credits/ContributorsCreditsCard.jsx
🧬 Code graph analysis (3)
src/pages/Credits/DependencyCreditsCard.jsx (3)
src/pages/Credits/ContributorsCreditsCard.jsx (1)
  • page (17-17)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/components/Pagination.jsx (1)
  • Pagination (16-88)
src/pages/Credits/StaticCreditsCard.jsx (2)
src/components/GlassCard.jsx (1)
  • GlassCard (5-9)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/pages/Credits/ContributorsCreditsCard.jsx (4)
src/components/Pagination.jsx (2)
  • i (9-9)
  • Pagination (16-88)
src/components/GlassCard.jsx (1)
  • GlassCard (5-9)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/components/FallbackImage.jsx (1)
  • FallbackImage (10-19)
🪛 GitHub Actions: CI
src/pages/Credits/ContributorsCreditsCard.jsx

[error] 1-1: ESLint: 'useEffect' is defined but never used. (no-unused-vars)

🪛 GitHub Check: Lint Code
src/pages/Credits/ContributorsCreditsCard.jsx

[failure] 1-1:
'useEffect' is defined but never used. Allowed unused vars must match /^[A-Z_]/u

🔇 Additional comments (12)
src/pages/Credits/Credits.module.css (1)

4-4: LGTM! Tighter spacing complements the pagination additions.

The reduced gap (2rem → 1rem) creates a denser layout that works well with the new paginated content structure.

src/components/Pagination.module.css (1)

1-64: LGTM! Well-structured pagination styles with accessibility and responsiveness.

The CSS module is cleanly organized with:

  • Proper use of CSS variables for theming
  • Smooth transitions for interactive states
  • Appropriate disabled state handling (opacity + cursor: not-allowed)
  • Mobile optimization for smaller screens
  • Clear visual hierarchy between arrows, pages, and ellipsis
src/pages/Credits/StaticCreditsCard.module.css (1)

1-13: LGTM! Clean table styling with appropriate specificity.

The use of !important on line 4 is justified to override inherited width styles. The nowrap on first-child prevents label wrapping while keeping content cells flexible.

src/pages/Credits/ContributorsCreditsCard.jsx (1)

17-17: LGTM! Pagination implementation is clean and correct.

The client-side pagination correctly:

  • Maintains page state with useState(0)
  • Renders only the current page's table (i === page)
  • Integrates the Pagination component with proper props

Also applies to: 24-60, 63-63

src/pages/Credits/StaticCreditsCard.jsx (1)

3-3: LGTM! CSS module integration is clean.

The import and application of the CSS module properly centralizes table styling.

Also applies to: 10-10

src/components/Pagination.jsx (1)

32-86: LGTM: Well-structured pagination UI with good accessibility.

The pagination rendering logic is solid:

  • Proper semantic <nav> with ARIA labels
  • Correct handling of edge cases (hidden when only 1 page)
  • Good accessibility with aria-current for active page
  • Appropriate disabled states for navigation controls
  • Clear visual feedback with ellipses for truncated ranges
src/pages/Credits/DependencyCreditsCard.jsx (4)

10-10: LGTM: Reasonable pagination constants and state initialization.

PAGE_SIZE of 10 provides good balance for readability without excessive scrolling, and the page state is correctly initialized to 0 for zero-indexed pagination.

Also applies to: 16-17


46-58: LGTM: Correct pagination logic and index calculations.

The pagination implementation correctly:

  • Slices items for the current page
  • Maps local indices to global indices via page * PAGE_SIZE + localIndex
  • Uses globalIndex to access the corresponding query in the full queries array
  • Generates unique keys with ${name}-${globalIndex}

64-77: LGTM: Well-implemented URL rendering with proper security and UX.

The URL rendering logic properly handles all states:

  • Loading feedback during fetch
  • Tooltip with descriptive content for accessibility
  • Secure external links with rel="noopener noreferrer"
  • Dual display (full URL + icon) with CSS-controlled visibility
  • Clear fallback message when URL is unavailable

93-93: LGTM: Correct Pagination integration with proper state management.

The Pagination component is properly integrated:

  • Independent page state for each section prevents interference
  • Math.ceil correctly handles partial pages
  • Direct setState references provide stable callbacks
  • Component automatically hides when pagination is unnecessary (≤1 page)

Also applies to: 101-101

src/pages/Credits/DependencyCreditsCard.module.css (2)

1-32: LGTM: Reasonable table layout with overflow handling.

The fixed table layout with explicit column widths (35% / 15% / 50%) provides consistent presentation:

  • Package names get adequate space with ellipsis for very long names
  • Versions get compact space appropriate for version strings
  • URLs get the most space as they tend to be longest

The text-overflow: ellipsis prevents layout breaks while keeping content accessible in the DOM.


42-71: LGTM: Effective mobile-responsive strategy.

The mobile breakpoint (600px) provides a well-optimized layout:

  • Full-width table maximizes available space
  • Package names get 50% allocation for better readability
  • URL column reduces to icon-only (40px) to conserve horizontal space
  • Icon size (18px from DependencyCreditsCard.jsx line 71) fits comfortably in 40px with proper tap target
  • vertical-align: middle ensures proper icon alignment

Comment thread src/components/Pagination.jsx
Comment thread src/pages/Credits/ContributorsCreditsCard.jsx Outdated

@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

🤖 Fix all issues with AI agents
In @src/pages/Credits/ContributorsCreditsCard.jsx:
- Line 54: The ContributorsCreditsCard still always renders "commits"; update
the rendering that uses c.contributions to choose the correct singular/plural
form (e.g., use a conditional on c.contributions === 1 to render "commit"
otherwise "commits") inside the ContributorsCreditsCard component where the <td>
displays contributions so a single contribution reads "1 commit" and others read
"N commits".
🧹 Nitpick comments (1)
src/pages/Credits/ContributorsCreditsCard.jsx (1)

24-60: Inefficient rendering pattern: mapping all tables to find current page.

The current implementation maps over all tables and conditionally renders only the active page. This creates unnecessary iterations.

♻️ More efficient approach using direct array access
       <div className={styles.contributorsGrid}>
-        {tables.map(
-          (group, i) =>
-            i === page && (
-              <table key={i}>
-                <tbody>
-                  {group.map((c) => (
-                    <tr key={c.id}>
-                      <td>
-                        <Tooltip content={`Open ${c.login}'s GitHub profile`}>
-                          <a href={c.html_url} target="_blank" rel="noopener noreferrer">
-                            <FallbackImage
-                              src={c.avatar_url}
-                              fallback={<User color="var(--color-text-light)" />}
-                              alt={c.login}
-                              width="28"
-                              height="28"
-                              className={styles.avatar}
-                            />
-                          </a>
-                        </Tooltip>
-                      </td>
-
-                      <td>
-                        <Tooltip content={`Visit ${c.login}'s GitHub profile`}>
-                          <a href={c.html_url} target="_blank" rel="noopener noreferrer">
-                            {c.login}
-                          </a>
-                        </Tooltip>
-                      </td>
-
-                      <td>{c.contributions} commits</td>
-                    </tr>
-                  ))}
-                </tbody>
-              </table>
-            )
-        )}
+        {tables[page] && (
+          <table>
+            <tbody>
+              {tables[page].map((c) => (
+                <tr key={c.id}>
+                  <td>
+                    <Tooltip content={`Open ${c.login}'s GitHub profile`}>
+                      <a href={c.html_url} target="_blank" rel="noopener noreferrer">
+                        <FallbackImage
+                          src={c.avatar_url}
+                          fallback={<User color="var(--color-text-light)" />}
+                          alt={c.login}
+                          width="28"
+                          height="28"
+                          className={styles.avatar}
+                        />
+                      </a>
+                    </Tooltip>
+                  </td>
+
+                  <td>
+                    <Tooltip content={`Visit ${c.login}'s GitHub profile`}>
+                      <a href={c.html_url} target="_blank" rel="noopener noreferrer">
+                        {c.login}
+                      </a>
+                    </Tooltip>
+                  </td>
+
+                  <td>{c.contributions} {c.contributions === 1 ? 'commit' : 'commits'}</td>
+                </tr>
+              ))}
+            </tbody>
+          </table>
+        )}
       </div>

Note: This also includes the grammar fix from the previous comment.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 788aa44 and cecbd3e.

📒 Files selected for processing (1)
  • src/pages/Credits/ContributorsCreditsCard.jsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 217
File: src/pages/Credits/ContributorsCreditsCard.jsx:48-50
Timestamp: 2026-01-09T14:45:56.443Z
Learning: In src/pages/Credits/ContributorsCreditsCard.jsx, the contributor data comes from GitHub's /contributors API endpoint (via scripts/generate-contributor-credits-json.js), which only returns contributors with at least one contribution. Therefore, c.contributions will always be >= 1 and the zero case is impossible.
📚 Learning: 2026-01-09T14:45:56.443Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 217
File: src/pages/Credits/ContributorsCreditsCard.jsx:48-50
Timestamp: 2026-01-09T14:45:56.443Z
Learning: In src/pages/Credits/ContributorsCreditsCard.jsx, the contributor data comes from GitHub's /contributors API endpoint (via scripts/generate-contributor-credits-json.js), which only returns contributors with at least one contribution. Therefore, c.contributions will always be >= 1 and the zero case is impossible.

Applied to files:

  • src/pages/Credits/ContributorsCreditsCard.jsx
🧬 Code graph analysis (1)
src/pages/Credits/ContributorsCreditsCard.jsx (4)
src/components/Pagination.jsx (2)
  • i (9-9)
  • Pagination (16-88)
src/components/GlassCard.jsx (1)
  • GlassCard (5-9)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/components/FallbackImage.jsx (1)
  • FallbackImage (10-19)
🔇 Additional comments (3)
src/pages/Credits/ContributorsCreditsCard.jsx (3)

1-8: LGTM: Imports are correct for pagination.

The added useState and Pagination imports are properly used in the component.


14-18: LGTM: State setup is appropriate.

The pagination state is correctly initialized, and the chunk size of 10 contributors per page is reasonable.


63-63: LGTM: Pagination component is correctly integrated.

The Pagination component receives the correct props (page, totalPages, onChange), and the state setter is appropriately used as the change handler.

Comment thread src/pages/Credits/ContributorsCreditsCard.jsx Outdated

@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

🤖 Fix all issues with AI agents
In @src/pages/Credits/ContributorsCreditsCard.jsx:
- Around line 24-60: The table cell currently renders only the label and drops
the numeric contribution count; update the cell that uses c.contributions
(inside ContributorsCreditsCard.jsx where tables.map and the row rendering
occurs) to include the numeric value followed by the pluralized label (e.g.,
render c.contributions then choose 'commit' vs 'commits' based on
c.contributions === 1). While here, you can also simplify rendering by using the
active page directly (use tables[page] instead of mapping all tables and
checking i === page) to avoid iterating unused pages.
🧹 Nitpick comments (2)
src/pages/Credits/ContributorsCreditsCard.jsx (2)

11-18: Prefer memoized/extracted chunking to avoid re-allocating on every render.
chunk, tables, and chunkSize are recreated each render; consider extracting chunk outside the component and/or using useMemo for tables.


63-63: Consider clamping page on change for extra safety.
Even though the control disables out-of-range navigation, a small wrapper prevents accidental invalid state if tables.length changes.

Example
-      <Pagination page={page} totalPages={tables.length} onChange={setPage} />
+      <Pagination
+        page={page}
+        totalPages={tables.length}
+        onChange={(p) => setPage(Math.max(0, Math.min(p, tables.length - 1)))}
+      />
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cecbd3e and c4aaaa8.

📒 Files selected for processing (1)
  • src/pages/Credits/ContributorsCreditsCard.jsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 217
File: src/pages/Credits/ContributorsCreditsCard.jsx:48-50
Timestamp: 2026-01-09T14:45:56.443Z
Learning: In src/pages/Credits/ContributorsCreditsCard.jsx, the contributor data comes from GitHub's /contributors API endpoint (via scripts/generate-contributor-credits-json.js), which only returns contributors with at least one contribution. Therefore, c.contributions will always be >= 1 and the zero case is impossible.
📚 Learning: 2026-01-09T14:45:56.443Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 217
File: src/pages/Credits/ContributorsCreditsCard.jsx:48-50
Timestamp: 2026-01-09T14:45:56.443Z
Learning: In src/pages/Credits/ContributorsCreditsCard.jsx, the contributor data comes from GitHub's /contributors API endpoint (via scripts/generate-contributor-credits-json.js), which only returns contributors with at least one contribution. Therefore, c.contributions will always be >= 1 and the zero case is impossible.

Applied to files:

  • src/pages/Credits/ContributorsCreditsCard.jsx
🧬 Code graph analysis (1)
src/pages/Credits/ContributorsCreditsCard.jsx (4)
src/components/Pagination.jsx (2)
  • i (9-9)
  • Pagination (16-88)
src/components/GlassCard.jsx (1)
  • GlassCard (5-9)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/components/FallbackImage.jsx (1)
  • FallbackImage (10-19)

Comment thread src/pages/Credits/ContributorsCreditsCard.jsx
laxitajain and others added 3 commits January 11, 2026 15:50
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@laxitajain laxitajain changed the title fix(credits-page): grammar correction on the credits page refactor(credits-page): standardized styling and added pagination Jan 11, 2026
@laxitajain

Copy link
Copy Markdown
Contributor Author

Hi @Ryan-Millard, please have a look, and let me know what you think:

Pagination

  • Added a reusable <Pagination /> component
  • Integrated pagination into:
    • Contributors table
    • Dependencies table
    • Dev Dependencies table
      (following standard practice, no pagination is shown if only one page exists.)
  • Supports:
    • Arrow-based navigation (‹ ›)
    • Page numbers with ellipsis for large datasets
    • Keyboard navigation

Consistent styling

  • Normalized table layouts across all Credits cards
  • Fixed column width issues (labels vs content)
  • Improved spacing, alignment, and visual balance
  • Ensured styles are scoped correctly via CSS Modules

Responsive improvements

  • Tables and pagination adapt cleanly to smaller screens
  • Reduced visual clutter on narrow viewports
  • Maintained readability without horizontal overflow
Show Screenshots
image Desktop – Dependencies Desktop – Dev Dependencies image Mobile view

@Ryan-Millard Ryan-Millard left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This is great! Thank you!

I just have a few small things to ask of you:

  1. Please write some tests for the Pagination component (and the other pages if you'd like - the Pagination component one is the most important since it may get used elsewhere in the code).
  2. Please will you write some documentation for the Pagination component inside docs/docs/reference/react/components/ so future contributors will know how to use it.
  3. Please will you add the glass global class (from global-styles/components.css) to the buttons to maintain consistency across the app.
  4. Please will you change the styling on the buttons (see my comment on Pagination.module.css). As you can see below, it's hard to read the numbers on the active ones in the dark theme:
Image

Comment thread src/components/Pagination.module.css

@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)
src/pages/Credits/ContributorsCreditsCard.jsx (2)

11-12: Consider moving the chunk utility outside the component.

The chunk function is pure and doesn't depend on component state or props. Moving it outside avoids recreating it on every render and improves readability.

♻️ Suggested refactor
 import { User } from 'lucide-react';
 
+const chunk = (arr, size) =>
+  Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => arr.slice(i * size, i * size + size));
+
 export default function ContributorsCreditsCard() {
-  const chunk = (arr, size) =>
-    Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => arr.slice(i * size, i * size + size));
-
   const chunkSize = 10;

24-60: Simplify rendering by directly accessing the current page's data.

The current pattern maps over all table groups but only renders one, producing an array like [false, false, <table>, false]. This is inefficient and harder to read. Directly access tables[page] instead.

♻️ Suggested refactor
       <div className={styles.contributorsGrid}>
-        {tables.map(
-          (group, i) =>
-            i === page && (
-              <table key={i}>
-                <tbody>
-                  {group.map((c) => (
-                    <tr key={c.id}>
-                      <td>
-                        <Tooltip content={`Open ${c.login}'s GitHub profile`}>
-                          <a href={c.html_url} target="_blank" rel="noopener noreferrer">
-                            <FallbackImage
-                              src={c.avatar_url}
-                              fallback={<User color="var(--color-text-light)" />}
-                              alt={c.login}
-                              width="28"
-                              height="28"
-                              className={styles.avatar}
-                            />
-                          </a>
-                        </Tooltip>
-                      </td>
-                      <td>
-                        <Tooltip content={`Visit ${c.login}'s GitHub profile`}>
-                          <a href={c.html_url} target="_blank" rel="noopener noreferrer">
-                            {c.login}
-                          </a>
-                        </Tooltip>
-                      </td>
-                      <td>
-                        {c.contributions} {c.contributions === 1 ? 'commit' : 'commits'}
-                      </td>
-                    </tr>
-                  ))}
-                </tbody>
-              </table>
-            )
-        )}
+        <table>
+          <tbody>
+            {tables[page]?.map((c) => (
+              <tr key={c.id}>
+                <td>
+                  <Tooltip content={`Open ${c.login}'s GitHub profile`}>
+                    <a href={c.html_url} target="_blank" rel="noopener noreferrer">
+                      <FallbackImage
+                        src={c.avatar_url}
+                        fallback={<User color="var(--color-text-light)" />}
+                        alt={c.login}
+                        width="28"
+                        height="28"
+                        className={styles.avatar}
+                      />
+                    </a>
+                  </Tooltip>
+                </td>
+                <td>
+                  <Tooltip content={`Visit ${c.login}'s GitHub profile`}>
+                    <a href={c.html_url} target="_blank" rel="noopener noreferrer">
+                      {c.login}
+                    </a>
+                  </Tooltip>
+                </td>
+                <td>
+                  {c.contributions} {c.contributions === 1 ? 'commit' : 'commits'}
+                </td>
+              </tr>
+            ))}
+          </tbody>
+        </table>
       </div>
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c4aaaa8 and 2d90df9.

📒 Files selected for processing (2)
  • src/components/Pagination.jsx
  • src/pages/Credits/ContributorsCreditsCard.jsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Pagination.jsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 217
File: src/pages/Credits/ContributorsCreditsCard.jsx:48-50
Timestamp: 2026-01-09T14:45:56.443Z
Learning: In src/pages/Credits/ContributorsCreditsCard.jsx, the contributor data comes from GitHub's /contributors API endpoint (via scripts/generate-contributor-credits-json.js), which only returns contributors with at least one contribution. Therefore, c.contributions will always be >= 1 and the zero case is impossible.
📚 Learning: 2026-01-09T14:45:56.443Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 217
File: src/pages/Credits/ContributorsCreditsCard.jsx:48-50
Timestamp: 2026-01-09T14:45:56.443Z
Learning: In src/pages/Credits/ContributorsCreditsCard.jsx, the contributor data comes from GitHub's /contributors API endpoint (via scripts/generate-contributor-credits-json.js), which only returns contributors with at least one contribution. Therefore, c.contributions will always be >= 1 and the zero case is impossible.

Applied to files:

  • src/pages/Credits/ContributorsCreditsCard.jsx
🧬 Code graph analysis (1)
src/pages/Credits/ContributorsCreditsCard.jsx (4)
src/components/Pagination.jsx (2)
  • i (9-9)
  • Pagination (16-94)
src/components/GlassCard.jsx (1)
  • GlassCard (5-9)
src/components/Tooltip.jsx (1)
  • Tooltip (5-35)
src/components/FallbackImage.jsx (1)
  • FallbackImage (10-19)
🔇 Additional comments (4)
src/pages/Credits/ContributorsCreditsCard.jsx (4)

1-8: LGTM!

Imports are appropriate for the added pagination functionality.


14-18: LGTM!

Chunk size of 10 is reasonable for table pagination, and the page state is correctly initialized.


52-53: Grammar fix correctly implemented.

The pluralization logic properly handles the singular "commit" case. Based on learnings, c.contributions is always >= 1 from the GitHub API, so both branches are valid.


63-63: Pagination integration looks correct.

The Pagination component receives the appropriate props and aligns with the reusable component's API shown in src/components/Pagination.jsx.

@Ryan-Millard

Ryan-Millard commented Jan 18, 2026

Copy link
Copy Markdown
Owner

Hi @laxitajain. Just checking in - are you still interested in this PR? There's no rush whatsoever. I'd just like to know if you're unable to complete it and would like someone else to pick up from where you left off.

@laxitajain

Copy link
Copy Markdown
Contributor Author

Hi @laxitajain. Just checking in - are you still interested in this PR? There's no rush whatsoever. I'd just like to know if you're unable to complete it and would like someone else to pick up from where you left off.

Hello, thanks for waiting. I apologize for not being able to update you sooner, I haven't been able to find time to continue work here. I'm still interested and shall make the required changes soon.

Co-authored-by: Ryan Millard <142347829+Ryan-Millard@users.noreply.github.com>
@Ryan-Millard

Copy link
Copy Markdown
Owner

No problem at all! I just wanted to check up on it.

@laxitajain

Copy link
Copy Markdown
Contributor Author

hey @Ryan-Millard, I've realised I won't be able to continue work on this PR and therefore will be revoking my claim on the issue. Sorry for the inconvenience!

@Ryan-Millard

Copy link
Copy Markdown
Owner

Hi @laxitajain. That's not a problem at all. Someone else will carry on from where you left off.

Have a good day!

@laxitajain

Copy link
Copy Markdown
Contributor Author

hey @Ryan-Millard!
I picked this one back up and implemented the changes you asked for.
Please will you have a look? :)

@Ryan-Millard Ryan-Millard left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thank you! This is wonderful.

@vercel

vercel Bot commented Jan 26, 2026

Copy link
Copy Markdown

@Ryan-Millard is attempting to deploy a commit to the Ryan Millard's projects Team on Vercel.

A member of the Team first needs to authorize it.

@Ryan-Millard

Copy link
Copy Markdown
Owner

Don't worry about Vercel's failure. I'm between changing hosts at the moment because GitHub Pages doesn't support setting headers and I haven't finished configuring Vercel.

@Ryan-Millard
Ryan-Millard merged commit f0749e9 into Ryan-Millard:main Jan 26, 2026
3 of 4 checks passed
@Ryan-Millard

Copy link
Copy Markdown
Owner

Thank you for your wonderful work so far @laxitajain!

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.

refactor(credits page): Standardize Credits Page Styling & Add Pagination to Dynamic Tables

2 participants