Skip to content

fix(deck): show card modal paging arrows and traverse whole deck#63

Merged
jcserv merged 2 commits into
mainfrom
fix-card-modal-paging
Jun 8, 2026
Merged

fix(deck): show card modal paging arrows and traverse whole deck#63
jcserv merged 2 commits into
mainfrom
fix-card-modal-paging

Conversation

@jcserv

@jcserv jcserv commented Jun 8, 2026

Copy link
Copy Markdown
Owner

The detail modal's Prev/Next controls never appeared. hasSiblings read the ordered-cards ref during render, but ref writes from the sync effect don't re-render the modal. On the dynamic(ssr:false) owner path the list mounts after the provider, so the modal kept reading an empty ref.

The fix:

  • Track the ordered-list length as reactive state (orderedCount) in DeckPreviewProvider; gate the arrows on it instead of the ref read so the modal re-renders when the list populates. The ref still backs cycle.
  • Include sorted sideboard + considering cards in the paging list so paging walks the whole deck (commander -> mainboard -> sideboard -> considering); those rows were clickable but previously excluded.
  • Add integration tests covering arrow visibility, sorted wrap-around paging, the async-mounted list path, and considering-zone cards.

Description

Fixes: #

Checklist

  • Tests pass (pnpm test) and lint is clean
  • New behavior is covered by tests
  • No revalidate / dynamic / unstable_cache — used 'use cache' + cacheLife/cacheTag
  • <Link> imported from app/_components/link.tsx, not next/link
  • Suspense fallbacks reserve layout space (explicit heights)

Screenshots / notes

Summary by CodeRabbit

Release Notes

  • New Features

    • Sideboard and considering cards now included in deck preview synchronization.
    • Added navigation controls (Next/Previous) to cycle through deck cards in preview.
  • Tests

    • Added test coverage for deck preview paging behavior and card navigation.

The detail modal's Prev/Next controls never appeared. `hasSiblings` read
the ordered-cards ref during render, but ref writes from the sync effect
don't re-render the modal. On the dynamic(ssr:false) owner path the list
mounts after the provider, so the modal kept reading an empty ref.

The fix:
- Track the ordered-list length as reactive state (orderedCount) in
  DeckPreviewProvider; gate the arrows on it instead of the ref read so
  the modal re-renders when the list populates. The ref still backs cycle.
- Include sorted sideboard + considering cards in the paging list so
  paging walks the whole deck (commander -> mainboard -> sideboard ->
  considering); those rows were clickable but previously excluded.
- Add integration tests covering arrow visibility, sorted wrap-around
  paging, the async-mounted list path, and considering-zone cards.
@jcserv jcserv self-assigned this Jun 8, 2026
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@jcserv, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 43 minutes and 45 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bbe44270-1ec1-40de-b8b0-02ee9e797234

📥 Commits

Reviewing files that changed from the base of the PR and between da419a0 and 1855f56.

📒 Files selected for processing (1)
  • app/_components/deck/deck-detail-sheet.test.tsx
📝 Walkthrough

Walkthrough

The PR extends deck preview paging to include sideboard and considering card zones. It computes these new zone-specific card lists in useDecklistState, updates useDecklistPreviewSync to include them in the ordered preview set, and adds reactive orderedCount tracking to the preview state context so paging controls appear once cards are loaded. New integration tests validate the complete paging flow across all zones.

Changes

Deck preview paging with sideboard and considering

Layer / File(s) Summary
Sideboard and considering card state computation
app/_components/builder/decklist.tsx
useDecklistState derives sideboardCards and consideringCards by filtering and sorting displayCards by zone, then returns both values for downstream use.
Preview sync function parameter expansion
app/_components/builder/decklist.tsx
useDecklistPreviewSync now accepts optional sideboardCards and consideringCards parameters and appends them to orderedPreviewFlat after mainboard sections.
Preview state context with orderedCount tracking
app/_components/deck/deck-preview-pane.tsx
PreviewStateValue adds orderedCount, DeckPreviewProvider manages it as state and updates it when setOrderedCards is called, and DeckDetailSheet reads it to determine whether paging controls should render.
Hook and component wiring for new card zones
app/_components/builder/decklist.tsx, app/_components/builder/decklist-dnd.tsx
Decklist and DecklistDnd destructure the new sideboardCards and consideringCards from useDecklistState and pass them into useDecklistPreviewSync.
Deck detail sheet paging integration tests
app/_components/deck/deck-detail-sheet.test.tsx
New test file validates paging behavior across mainboard and sideboard/considering zones by rendering the deck list under DeckPreviewProvider and DndContext, verifying controls appear, navigation respects sort order with wrap-around, and lazy-loaded mounting still shows controls.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A rabbit's ode to paging bliss:
Sideboard and considering, now synchronized with glee,
State flows through contexts, orderedCount set free,
Next and previous arrows guide the seeker's spree,
Through mainboard, sideboard—all zones paged perfectly! 🃏

🚥 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 PR title 'fix(deck): show card modal paging arrows and traverse whole deck' directly summarizes the main changes: fixing visibility of paging controls and enabling full-deck traversal including sideboard/considering zones.
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 fix-card-modal-paging

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: 2

🤖 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/deck/deck-detail-sheet.test.tsx`:
- Around line 245-247: The Suspense fallback currently renders a zero-height
<div> which violates the rule requiring reserved layout space; update the
Suspense fallback that wraps LazyList so the fallback element (the <div> inside
the Suspense) uses an explicit pixel height (for example by adding a Tailwind
class like h-[20px] or an inline style height: '20px') to reserve space while
loading; locate the Suspense that renders <LazyList /> in
deck-detail-sheet.test.tsx and modify its fallback element to include the
explicit height.
- Around line 14-19: The tests mock for "`@/app/_actions/deck/categories`" is
missing moveCategoryCards which DecklistDnd imports—add moveCategoryCards:
vi.fn() to the vi.mock(...) object to avoid import/runtime errors; also update
the Suspense fallback in deck-detail-sheet.test.tsx (the
fallback={<div>loading</div>} used by Suspense) to reserve layout space by
giving it a fixed height, e.g. change to fallback={<div
className="h-[20px]">loading</div>} so the test layout remains stable.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 88ecb8e2-0158-4c5a-b74e-a4faf07d025b

📥 Commits

Reviewing files that changed from the base of the PR and between d6db512 and da419a0.

📒 Files selected for processing (4)
  • app/_components/builder/decklist-dnd.tsx
  • app/_components/builder/decklist.tsx
  • app/_components/deck/deck-detail-sheet.test.tsx
  • app/_components/deck/deck-preview-pane.tsx

Comment thread app/_components/deck/deck-detail-sheet.test.tsx
Comment thread app/_components/deck/deck-detail-sheet.test.tsx Outdated
DecklistDnd imports moveCategoryCards from the categories actions, but
the deck-detail-sheet test mock omitted it, leaving the binding
undefined and risking a runtime error if a DnD move fired.

Changes:
- Add moveCategoryCards to the categories vi.mock
- Give the lazy-list Suspense fallback an explicit h-[20px] to satisfy
  the reserved-layout-space convention
@jcserv jcserv merged commit 5937acc into main Jun 8, 2026
5 checks passed
@jcserv jcserv deleted the fix-card-modal-paging branch June 8, 2026 22:10
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