Introduce a follow/unfollow feature for clubs in the ClubSummary component.
Users can now toggle their subscription status to a specific club, with
the state persisted locally using zustand.
Changes include:
- Added 'Follow' and 'Unfollow' buttons with corresponding star icons (StarOutlined/StarFilled).
- Updated ClubStore to manage a simplified list of clubs (id and name only).
- Refactored Data type in ClubSearchTable to use Pick<ClubInfo, 'id' | 'name'>.
- Fixed club name in GameSelector clubList to '东华乒乓球俱乐部'.
- Excluded follow buttons for club ID '47' (Donghua).
The implementation ensures a consistent UI state across the application
and persists user preferences.
- Refactor ClubEventList to support persistent page state in sessionStorage and dynamic toggle for finished events.
- Move pagination logic to useRunOnce hook for initialization, ensuring correct state restoration.
- Update ClubSearchTable to support "My Favorites" tab, using useRef to cache search results for different club types.
- Enhance EventCard with precise time formatting (HH:mm:ss) and dynamic countdown logic using dayjs timezone.
- Persist club selection in GameSelector using local storage and integrate ClubSummary component.
- Fix geo data handling in KaiqiuService, ensuring coordinates are correctly passed to iCalendar generator.
- Remove unused imports and simplify component structure across affected files.
- Add 'Club' vs 'Points Club' filter in `ClubSearchTable` using Radio buttons.
- Update `searchClub` request to accept and pass `clubType` parameter to the backend API.
- Refactor logic in `ClubEventList` to determine "Show All" button visibility based on whether all items are finished or not finished, rather than just a fixed count.
- Add custom CSS (styled-components) to limit the height of the game selector drawer for better UX.
- Update backend service `KaiqiuService` to handle the new query parameters for filtering clubs by type.
- Add 'ics' dependency to package.json and update lockfile.
- Introduce pagination support in `ClubEventList` component (Ant Design Pagination + Spin loading state).
- Refactor `GameSelector` to fetch paginated data (`page` query parameter) and manage page state.
- Update `KaiqiuService` to:
- Add Redis caching for event lists (1 hour TTL) and individual match details (10 hours TTL).
- Implement `listClubEvents` method with pagination support (fetching HTML, parsing titles/urls/status, extracting total count).
- Update `getEventInfo` to utilize cached data.
- Update server routes (`index.tsx`, `routes.tsx`) to handle query parameters and pass paginated responses to the frontend.
- Fix logic in `GroupingPrediction` to set group length when players <= 12.
This change improves performance by reducing initial load times through pagination and caching, preventing UI freezing with large event lists.
- **Frontend Refactoring**: Extracted EventCard logic and finished game filtering from GameSelector into a new ClubEventsList component. Removed direct routing logic (handleGameClick, navigate) from App.tsx in favor of router loaders.
- **New Feature - Club Detail Page**: Implemented /club/:id route with ClubEventsPage. Added server-side loader to fetch club info and events in parallel via new API endpoints (/api/club/find, /api/club/:id). Created KaiqiuService for direct data fetching.
- **API & Types**: Extended IEventInfo with isFinished flag; updated server-side parsing in utils/server.ts. Added ClubInfo type definition. Migrated club search and filtering logic to the server side.
- **Dependencies**: Updated antd from 6.2.1 to 6.3.2.