Skip to content

fix(web): resolve QueryClient server-to-client error and refactor to React Query#10

Merged
metacurb merged 11 commits into
mainfrom
fix/query-client-server-client-error
Oct 21, 2025
Merged

fix(web): resolve QueryClient server-to-client error and refactor to React Query#10
metacurb merged 11 commits into
mainfrom
fix/query-client-server-client-error

Conversation

@metacurb

@metacurb metacurb commented Oct 21, 2025

Copy link
Copy Markdown
Member

🐛 Problem

The application was throwing a Next.js error: "Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported." This occurred because the QueryClient class instance was being passed from a server component (layout.tsx) to client components.

Additionally, there was a nested modal issue where clicking "How to Play" in the header would open a modal containing another "How to Play" button.

🔧 Solution

This PR addresses both issues and includes a comprehensive refactor to improve the codebase:

QueryClient Fix

  • Created QueryProvider client component wrapper to handle QueryClient instantiation on the client side
  • Moved QueryClient from server component to client-side provider
  • Fixed Next.js error about passing class instances to Client Components

Modal Fix

  • Extracted HowToPlayContent component for reusability
  • Fixed Header component to use content directly instead of nested modal
  • Eliminated nested modal issue

React Query Migration

  • Added useUser hook for centralized user state management
  • Added useGameQuery hook for game data fetching with automatic polling
  • Migrated game pages from manual state management to React Query hooks
  • Improved error handling and loading states across components

UI Component Improvements

  • Added reusable icon components (close, eye)
  • Created display-name-editor component for user name updates
  • Added board-position and game-piece components for game board
  • Extracted reusable components from existing code

📋 Changes

  • ✅ Fixed QueryClient server-to-client component error
  • ✅ Resolved nested modal issue in How to Play
  • ✅ Added React Query hooks for data management
  • ✅ Created reusable UI components
  • ✅ Refactored game pages to use new hook patterns
  • ✅ Updated components to work with new data patterns
  • ✅ Improved error handling and loading states

🧪 Testing

  • Application loads without QueryClient error
  • How to Play modal shows content correctly (no nested modals)
  • Game pages load and function with new React Query hooks
  • User management works with new useUser hook
  • All existing functionality preserved

📝 Notes

This refactor significantly improves the codebase by:

  • Centralizing data fetching logic in reusable hooks
  • Eliminating manual polling in favor of React Query's built-in refetchInterval
  • Improving component reusability and maintainability
  • Following React Query best practices for data management

Note

Adds action history to game APIs and refactors the web app to React Query with a client-side QueryProvider and UI/component extractions.

  • API:
    • Game retrieval: GET /games/:id now accepts ?includeHistory=true and returns actionHistory via mapGameToGameResponse.
    • Action history: GamesService.getActionHistory now maps entities to response DTOs; getByIdWithDerivedState accepts includeHistory flag.
    • Controllers: Updated signatures/return types; added ActionHistoryResponse typing; new mappers: map-action-history-to-response.
  • Shared DTOs:
    • Added action-history.dto and exported types; extended GameResponse with optional actionHistory.
  • Web:
    • React Query: Introduced QueryProvider in app/layout.tsx; added useUser, useGameQuery, useGamesListQuery; migrated pages games/[id] and games to hooks with polling and improved error/loading.
    • API client: api.getGame(id, secret, includeHistory) and typed getActionHistory.
    • UI refactor: Extracted board-position, game-piece, display-name-editor, HowToPlayContent; updated Header to use content directly (fixing nested modal).
  • Tests:
    • Adjusted tests and fixtures for new fields and API behaviors.
  • Deps:
    • Bumped @tanstack/react-query; added query client setup (lib/query-client).

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

- Create QueryProvider client component wrapper
- Move QueryClient instantiation to client-side component
- Fix Next.js error about passing class instances to Client Components
- Remove unused Move import from action-history.dto.ts
- Extract HowToPlayContent component for reusability
- Fix Header component using HowToPlayContent directly
- Eliminate nested modal where clicking How to Play opened another How to Play button
- Maintain existing HowToPlay component for landing page compatibility
- Remove redundant position reference in setup description
- Remove historical context section for cleaner, more focused content
- Add useUser hook for user state management
- Add useGameQuery hook for game data fetching with polling
- Add query-client configuration with retry logic
- Extract data fetching logic from components into reusable hooks
- Add icon components (close, eye) for consistent UI
- Add display-name-editor component for user name updates
- Add board-position and game-piece components for game board
- Extract reusable components from existing code
- Replace manual state management with useUser and useGameQuery hooks
- Remove polling logic in favor of React Query's refetchInterval
- Simplify game detail page by removing manual data fetching
- Update games list page to use new hook pattern
- Improve error handling and loading states
- Update Board component to work with new data structure
- Update GamesList component to use React Query hooks
- Improve component props and data handling
- Maintain existing functionality while using new patterns
- Update API client to work with new hook patterns
- Improve error handling and response types
- Maintain backward compatibility with existing endpoints
cursor[bot]

This comment was marked as outdated.

- Add React imports to board-position.tsx and display-name-editor.tsx
- Add global React setup in test-setup.ts for JSX support
- Update games.controller.test.ts to expect includeHistory parameter
- All tests now passing across web, api, and shared packages
- Fix React namespace issue by removing global declaration
- Add missing boardState properties to test mock data
- Fix API mock return values to match expected GameResponse type
- All TypeScript errors resolved and tests passing
@metacurb metacurb merged commit 024a088 into main Oct 21, 2025
2 checks passed
@metacurb metacurb deleted the fix/query-client-server-client-error branch October 21, 2025 09:50
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