Skip to content

Upcoming subscriptions fix#1645

Merged
prxt6529 merged 8 commits intomainfrom
upcoming-subs-fix
Dec 12, 2025
Merged

Upcoming subscriptions fix#1645
prxt6529 merged 8 commits intomainfrom
upcoming-subs-fix

Conversation

@prxt6529
Copy link
Copy Markdown
Collaborator

@prxt6529 prxt6529 commented Dec 12, 2025

Summary by CodeRabbit

  • New Features

    • Added a seasons grid selector (desktop & mobile) and optional filter label on dropdowns; added transaction-type filters (Transfers, Burns).
  • Bug Fixes & Improvements

    • Upcoming drops now aggregate across seasons; subscription and redeemed rows show season labels; headings simplified to a generic "Upcoming Drops".
    • Activity and collection filters updated for clearer labels.
  • Styling & Layout

    • Updated spacing, link/button text styles, and table text color for improved readability.

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

Signed-off-by: prxt6529 <prxt@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 12, 2025

Warning

Rate limit exceeded

@prxt6529 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 4 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 491b261 and 6ad382b.

📒 Files selected for processing (4)
  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx (1 hunks)
  • components/user/collected/filters/UserPageCollectedFilters.tsx (6 hunks)
  • components/user/collected/filters/UserPageCollectedFiltersSzn.tsx (1 hunks)
  • components/utils/select/dropdown/SeasonsGridDropdown.tsx (1 hunks)

Walkthrough

Replaces MEMES_SEASON with MemeSeason entities, adds seasonIndex on mint rows and cross‑season mint helpers, introduces SeasonsGridDropdown (desktop/mobile wrappers), updates select/dropdown primitives and activity enums/filters, and applies broad UI, component, and test updates across the codebase.

Changes

Cohort / File(s) Summary
Meme calendar helpers & types
components/meme-calendar/meme-calendar.helpers.tsx
Add SeasonMintRow.seasonIndex; add getUpcomingMintsForSeasonIndex and getUpcomingMintsAcrossSeasons; unify seasonIndex propagation and adjust current/next-season rollover logic.
Calendar UI & subscriptions
components/meme-calendar/MemeCalendarOverview.tsx, components/meme-calendar/...NextMint* (…), components/subscriptions-report/SubscriptionsReport.tsx, components/user/subscriptions/UserPageSubscriptionsUpcoming.tsx
Switch to getUpcomingMintsAcrossSeasons returning SeasonMintRow[]; change memo types and data flow; remove per‑SZN headings in some places; update date/season label rendering and some empty-state text.
Seasons grid dropdown (new)
components/utils/select/dropdown/SeasonsGridDropdown.tsx, components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx, components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx, components/utils/select/dropdown/SeasonsGridDropdownMobileWrapper.tsx
New SeasonsGridDropdown and supporting desktop/mobile wrappers and items wrapper: fetches seasons from API, supports initialSeasonId, portal positioning, click-away/escape, responsive rendering, and animated open/close.
Select / Dropdown primitives
components/utils/select/CommonSelect.tsx, components/utils/select/dropdown/CommonDropdown.tsx
Add optional showFilterLabel prop to select/dropdown primitives; when enabled CommonDropdown renders a filter label before the main label.
Activity filters & header
components/latest-activity/ActivityFilters.tsx, components/latest-activity/ActivityHeader.tsx, components/latest-activity/LatestActivity.module.scss
Replace react-bootstrap Dropdowns with CommonDropdowns; expand ActivityFilters props (selectedContract, onTypeFilterChange, onContractFilterChange, isMobile); apply Tailwind utility classes; remove a .filterDropdown line-height rule.
Activity data hook & enums
hooks/useActivityData.ts
Update enum values (TypeFilter.ALL → "All Transactions", ContractFilter.ALL → "All Collections", ContractFilter.MEMES → "The Memes"); add TRANSFERS/BURNS; export UseActivityDataReturn interface.
User collected / season typing & filters
components/user/collected/*, components/user/collected/filters/*, components/user/collected/cards/*
Replace MEMES_SEASON enum usage with MemeSeason entities, add `initialSznId: number
Home & minor UI tweaks
components/home/Home.tsx, components/latest-activity/ActivityHeader.tsx, components/user/subscriptions/UserPageSubscriptions.module.scss
Small spacing/styling tweaks (tailwind classes), wrap link text in styled span, change table cell text color from #ddd to #fff.
Removed SeasonsDropdown
components/seasons-dropdown/SeasonsDropdown.tsx, components/seasons-dropdown/SeasonsDropdown.module.scss, __tests__/components/seasons-dropdown/SeasonsDropdown.test.tsx
Remove old SeasonsDropdown component, its stylesheet, and its test (replaced by the new SeasonsGridDropdown implementation and tests).
Tests & mocks
__tests__/**/* (multiple files; see diff)
Update tests and mocks to new helper names (getUpcomingMintsAcrossSeasons, displayedSeasonNumberFromIndex), include seasonIndex in mocks, adapt label expectations ("All Collections", "All Transactions"), swap dropdown mocks, and convert many tests to role-based/accessibility queries.
Enums
enums.ts
Remove exported MEMES_SEASON enum.

Sequence Diagram(s)

sequenceDiagram
    participant Parent as Parent (TheMemes / UserPageCollected)
    participant Dropdown as SeasonsGridDropdown
    participant API as new_memes_seasons API
    participant Wrapper as Desktop/Mobile Wrapper

    Parent ->> Dropdown: render(selected?, initialSeasonId?)
    Dropdown ->> API: GET /new_memes_seasons (on mount)
    API -->> Dropdown: seasons list
    Dropdown ->> Dropdown: apply initialSeasonId (if provided) and set selected
    User ->> Dropdown: click button (open)
    Dropdown ->> Wrapper: render items (isOpen=true)
    User ->> Wrapper: select season (or "All Seasons")
    Wrapper ->> Parent: setSelected(season | null)
    Parent -->> Dropdown: receive new selected prop / close
    Wrapper ->> Wrapper: animate close, cleanup listeners
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to focus:
    • components/meme-calendar/meme-calendar.helpers.tsx — correctness of cross-season accumulation, seasonIndex assignment, and rollover edge cases.
    • components/utils/select/dropdown/SeasonsGridDropdown* — API fetch cancellation (AbortController), initialSeasonId application, positioning math, portal behavior, click-away and Escape handling, and responsive wrapper switching.
    • components/user/collected* — conversions from MemeSeason to numeric id, URL/query construction, and updated handler signatures.
    • Tests — many mocks and expectations changed; ensure updated mocks match new public API and data shapes.

Possibly related PRs

Suggested reviewers

  • ragnep

Poem

🐇 I hopped through arrays and seasoned rows,
I stitched each mint where the warm wind blows.
A grid unfurled, the dropdown opened wide,
Seasons aligned — the choices now decide.
— a rabbit, nibbling code carrots 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Upcoming subscriptions fix' is vague and generic, using a non-descriptive term 'fix' without clearly conveying the specific changes made in the changeset. Consider using a more specific title that describes the primary change, such as 'Refactor upcoming subscriptions to use cross-season mint retrieval' or 'Update subscriptions to display season information in upcoming mints'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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
Copy Markdown

@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: 0

🧹 Nitpick comments (2)
components/latest-activity/ActivityFilters.tsx (1)

29-48: Consider memoizing the items arrays.

The Object.values(...).map(...) calls on lines 30-34 and 40-44 recreate the items arrays on every render. Since the enum values are static, wrapping these in useMemo would avoid unnecessary object creation.

Apply this refactor to memoize the items:

+"use client";
+
+import CommonDropdown from "@/components/utils/select/dropdown/CommonDropdown";
+import { ContractFilter, TypeFilter } from "@/hooks/useActivityData";
+import { useMemo } from "react";
+import { Col } from "react-bootstrap";
+
 interface ActivityFiltersProps {
   readonly typeFilter: TypeFilter;
   readonly selectedContract: ContractFilter;
   readonly onTypeFilterChange: (filter: TypeFilter) => void;
   readonly onContractFilterChange: (contract: ContractFilter) => void;
   readonly isMobile: boolean;
 }
 
 export default function ActivityFilters({
   typeFilter,
   selectedContract,
   onTypeFilterChange,
   onContractFilterChange,
   isMobile,
 }: ActivityFiltersProps) {
+  const contractItems = useMemo(
+    () => Object.values(ContractFilter).map((contract) => ({
+      key: contract,
+      label: contract,
+      value: contract,
+    })),
+    []
+  );
+
+  const typeItems = useMemo(
+    () => Object.values(TypeFilter).map((type) => ({
+      key: type,
+      label: type,
+      value: type,
+    })),
+    []
+  );
+
   return (
     <Col
       sm={12}
       md={6}
       className={`tailwind-scope tw-py-2 d-flex align-items-center gap-4 ${
         isMobile ? "justify-content-center" : "justify-content-end"
       }`}>
       <CommonDropdown
-        items={Object.values(ContractFilter).map((contract) => ({
-          key: contract,
-          label: contract,
-          value: contract,
-        }))}
+        items={contractItems}
         activeItem={selectedContract}
         filterLabel="Collection"
         setSelected={onContractFilterChange}
       />
       <CommonDropdown
-        items={Object.values(TypeFilter).map((type) => ({
-          key: type,
-          label: type,
-          value: type,
-        }))}
+        items={typeItems}
         activeItem={typeFilter}
         filterLabel="Filter"
         setSelected={onTypeFilterChange}
       />
     </Col>
   );
 }
__tests__/app/tools/subscriptions-report.test.tsx (1)

7-12: Consider adding mocks for displayedSeasonNumberFromIndex and formatFullDate.

The component uses displayedSeasonNumberFromIndex and formatFullDate from the helpers module. While the test passes because these are used only in rendered content (not in assertions), explicitly mocking them would make the test more robust and prevent potential issues if the real implementations have side effects or complex logic.

 jest.mock("@/components/meme-calendar/meme-calendar.helpers", () => ({
   __esModule: true,
   getCardsRemainingUntilEndOf: jest.fn(() => 2),
   getUpcomingMintsAcrossSeasons: jest.fn(() => []),
   isMintingToday: jest.fn(() => false),
+  displayedSeasonNumberFromIndex: jest.fn((idx: number) => idx + 1),
+  formatFullDate: jest.fn(() => "Mon, 1 Jan 2024"),
 }));
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between da0508b and 0777a6c.

📒 Files selected for processing (17)
  • __tests__/app/tools/subscriptions-report.test.tsx (2 hunks)
  • __tests__/components/latest-activity/ActivityHeader.test.tsx (1 hunks)
  • __tests__/components/latest-activity/LatestActivity.test.tsx (5 hunks)
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx (2 hunks)
  • __tests__/hooks/useActivityFilters.test.ts (2 hunks)
  • components/home/Home.tsx (1 hunks)
  • components/latest-activity/ActivityFilters.tsx (2 hunks)
  • components/latest-activity/ActivityHeader.tsx (1 hunks)
  • components/latest-activity/LatestActivity.module.scss (0 hunks)
  • components/meme-calendar/MemeCalendarOverview.tsx (3 hunks)
  • components/meme-calendar/meme-calendar.helpers.tsx (4 hunks)
  • components/subscriptions-report/SubscriptionsReport.tsx (7 hunks)
  • components/user/subscriptions/UserPageSubscriptions.module.scss (1 hunks)
  • components/user/subscriptions/UserPageSubscriptionsUpcoming.tsx (4 hunks)
  • components/utils/select/CommonSelect.tsx (2 hunks)
  • components/utils/select/dropdown/CommonDropdown.tsx (2 hunks)
  • hooks/useActivityData.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • components/latest-activity/LatestActivity.module.scss
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version

**/*.{ts,tsx,js,jsx}: Replace <img> elements with <Image /> from next/image to satisfy @next/next/no-img-element ESLint rule
Use <Link href="/path"> from Next.js for internal navigation instead of plain HTML links to satisfy @next/next/no-html-link-for-pages ESLint rule

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • components/utils/select/dropdown/CommonDropdown.tsx
  • components/latest-activity/ActivityHeader.tsx
  • components/meme-calendar/meme-calendar.helpers.tsx
  • components/home/Home.tsx
  • components/utils/select/CommonSelect.tsx
  • components/user/subscriptions/UserPageSubscriptionsUpcoming.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
  • components/latest-activity/ActivityFilters.tsx
  • components/subscriptions-report/SubscriptionsReport.tsx
  • components/meme-calendar/MemeCalendarOverview.tsx
  • hooks/useActivityData.ts
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always add readonly before props in React components

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • components/utils/select/dropdown/CommonDropdown.tsx
  • components/latest-activity/ActivityHeader.tsx
  • components/meme-calendar/meme-calendar.helpers.tsx
  • components/home/Home.tsx
  • components/utils/select/CommonSelect.tsx
  • components/user/subscriptions/UserPageSubscriptionsUpcoming.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
  • components/latest-activity/ActivityFilters.tsx
  • components/subscriptions-report/SubscriptionsReport.tsx
  • components/meme-calendar/MemeCalendarOverview.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use <Link>, images should use next/image, and adopt Next's ESLint rules (Core Web Vitals)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • components/utils/select/dropdown/CommonDropdown.tsx
  • components/latest-activity/ActivityHeader.tsx
  • components/meme-calendar/meme-calendar.helpers.tsx
  • components/home/Home.tsx
  • components/utils/select/CommonSelect.tsx
  • components/user/subscriptions/UserPageSubscriptionsUpcoming.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
  • components/latest-activity/ActivityFilters.tsx
  • components/subscriptions-report/SubscriptionsReport.tsx
  • components/meme-calendar/MemeCalendarOverview.tsx
  • hooks/useActivityData.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Must pass tsc --noEmit type checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") over React. namespace usage (React.useMemo, React.useRef, etc.)
If the react-hooks/exhaustive-deps lint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic in useEffectEvent

**/*.{ts,tsx}: Must pass tsc --noEmit for TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
Use useEffectEvent for non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs: <Link> for internal links, next/image for images, adopt Next's ESLint rules
Use 'use cache' directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace <img> elements with <Image /> from next/image
Use <Link href="/path"> for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with 'use server' directive

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • components/utils/select/dropdown/CommonDropdown.tsx
  • components/latest-activity/ActivityHeader.tsx
  • components/meme-calendar/meme-calendar.helpers.tsx
  • components/home/Home.tsx
  • components/utils/select/CommonSelect.tsx
  • components/user/subscriptions/UserPageSubscriptionsUpcoming.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
  • components/latest-activity/ActivityFilters.tsx
  • components/subscriptions-report/SubscriptionsReport.tsx
  • components/meme-calendar/MemeCalendarOverview.tsx
  • hooks/useActivityData.ts
**/@(__tests__|*.test).{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Tests should live in __tests__/ or ComponentName.test.tsx; mock external dependencies and APIs in tests

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Place tests in __tests__/ directory or as ComponentName.test.tsx alongside components

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Mock external dependencies and APIs in tests

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
__tests__/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use Jest + ts-jest for TypeScript testing

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
__tests__/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (tests/AGENTS.md)

__tests__/**/*.{ts,tsx,js}: Prefer for...of loops over forEach as it allows break/continue and works with async/await
Use array.at(-1) and array.at(-2) instead of index-based array access for negative indexing
Use String.prototype.replaceAll() instead of replace() for global string replacements
Use globalThis.fetch() instead of direct fetch() calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Use element.remove() instead of parent.removeChild(element) for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use semantic HTML elements (<label>, <output>) over ARIA attributes when possible; every form control must have a label

Files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
🧠 Learnings (23)
📓 Common learnings
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/{components,contexts,hooks}/**/*.{ts,tsx} : Use semantic HTML elements (`<label>`, `<output>`) over ARIA attributes when possible; every form control must have a label

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • components/utils/select/CommonSelect.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/@(__tests__|*.test).{ts,tsx} : Tests should live in `__tests__/` or `ComponentName.test.tsx`; mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Test high-risk areas including happy path workflows, invalid input errors, edge cases/boundaries, component & API interactions, and performance/security when relevant

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/__tests__/**/*.{ts,tsx} : Place tests in `__tests__/` directory or as `ComponentName.test.tsx` alongside components

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Use testing-library/react + user-event for React component tests

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • components/latest-activity/ActivityHeader.tsx
  • components/home/Home.tsx
  • components/utils/select/CommonSelect.tsx
  • components/user/subscriptions/UserPageSubscriptionsUpcoming.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
  • components/latest-activity/ActivityFilters.tsx
  • components/subscriptions-report/SubscriptionsReport.tsx
  • components/meme-calendar/MemeCalendarOverview.tsx
  • hooks/useActivityData.ts
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Test accessibility with keyboard navigation and screen reader compatibility

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Write tests following Arrange – Act – Assert pattern with one behaviour per test and clear, descriptive names

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : All tests must live in `__tests__`, mirroring source folders (`components`, `contexts`, `hooks`, `utils`)

Applied to files:

  • __tests__/components/latest-activity/LatestActivity.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Organize imports with one import per module in order: external → internal → types, with no duplicates

Applied to files:

  • __tests__/hooks/useActivityFilters.test.ts
  • __tests__/components/latest-activity/ActivityHeader.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: TypeScript + React functional components with hooks; follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Applied to files:

  • __tests__/hooks/useActivityFilters.test.ts
  • components/utils/select/CommonSelect.tsx
  • components/latest-activity/ActivityFilters.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Keep tests independent, deterministic, and fast with production-like data

Applied to files:

  • __tests__/hooks/useActivityFilters.test.ts
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Use `String.prototype.replaceAll()` instead of `replace()` for global string replacements

Applied to files:

  • __tests__/hooks/useActivityFilters.test.ts
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx} : Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic

Applied to files:

  • __tests__/hooks/useActivityFilters.test.ts
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use `<Link href="/path">` for internal navigation instead of plain HTML links

Applied to files:

  • components/latest-activity/ActivityHeader.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use TailwindCSS for styling in React components

Applied to files:

  • components/latest-activity/ActivityHeader.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `<Link href="/path">` from Next.js for internal navigation instead of plain HTML links to satisfy `next/next/no-html-link-for-pages` ESLint rule

Applied to files:

  • components/latest-activity/ActivityHeader.tsx
  • components/home/Home.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use framework APIs: `<Link>` for internal links, `next/image` for images, adopt Next's ESLint rules

Applied to files:

  • components/latest-activity/ActivityHeader.tsx
  • components/home/Home.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks

Applied to files:

  • components/utils/select/CommonSelect.tsx
  • components/latest-activity/ActivityFilters.tsx
  • hooks/useActivityData.ts
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
  • __tests__/app/tools/subscriptions-report.test.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use react-query for data fetching

Applied to files:

  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx
🧬 Code graph analysis (7)
components/home/Home.tsx (2)
helpers/nextgen-utils.ts (1)
  • formatNameForUrl (1-3)
components/nextGen/nextgen_helpers.ts (1)
  • formatNameForUrl (588-588)
components/user/subscriptions/UserPageSubscriptionsUpcoming.tsx (1)
components/meme-calendar/meme-calendar.helpers.tsx (4)
  • SeasonMintRow (846-851)
  • getUpcomingMintsAcrossSeasons (948-963)
  • displayedSeasonNumberFromIndex (368-379)
  • formatFullDate (669-677)
__tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx (2)
__tests__/utils/testContexts.tsx (1)
  • createMockAuthContext (25-38)
tests/testHelpers.ts (1)
  • test (4-11)
__tests__/app/tools/subscriptions-report.test.tsx (1)
app/page.tsx (1)
  • Page (14-47)
components/latest-activity/ActivityFilters.tsx (2)
components/utils/select/dropdown/CommonDropdown.tsx (1)
  • CommonDropdown (11-187)
hooks/useActivityData.ts (1)
  • ContractFilter (128-128)
components/subscriptions-report/SubscriptionsReport.tsx (1)
components/meme-calendar/meme-calendar.helpers.tsx (4)
  • SeasonMintRow (846-851)
  • getUpcomingMintsAcrossSeasons (948-963)
  • displayedSeasonNumberFromIndex (368-379)
  • formatFullDate (669-677)
components/meme-calendar/MemeCalendarOverview.tsx (2)
components/meme-calendar/meme-calendar.helpers.tsx (5)
  • SeasonMintScanResult (853-862)
  • getUpcomingMintsForCurrentOrNextSeason (915-937)
  • getCanonicalNextMintNumber (965-975)
  • getUpcomingMintsForSeasonIndex (939-946)
  • displayedSeasonNumberFromIndex (368-379)
helpers/time.ts (1)
  • now (7-9)
🪛 GitHub Check: SonarCloud Code Analysis
__tests__/hooks/useActivityFilters.test.ts

[failure] 369-369: Refactor this code to not nest functions more than 4 levels deep.

See more on https://sonarcloud.io/project/issues?id=6529-Collections_6529seize-frontend&issues=AZsST81JmPgnbCdmYFud&open=AZsST81JmPgnbCdmYFud&pullRequest=1645


[failure] 285-285: Refactor this code to not nest functions more than 4 levels deep.

See more on https://sonarcloud.io/project/issues?id=6529-Collections_6529seize-frontend&issues=AZsST81JmPgnbCdmYFuc&open=AZsST81JmPgnbCdmYFuc&pullRequest=1645

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (21)
components/user/subscriptions/UserPageSubscriptions.module.scss (1)

27-40: LGTM: table cell text color update is safe and consistent with existing specificity.
Purely presentational change; no functional risk. Consider a future cleanup pass to reduce !important usage if feasible.

__tests__/components/latest-activity/LatestActivity.test.tsx (1)

116-117: LGTM! Test assertions updated to match new UI labels.

The test selectors correctly reflect the updated enum values from hooks/useActivityData.ts (e.g., "All Collections", "The Memes", "All Transactions").

Also applies to: 173-173, 409-409, 429-430, 455-456

components/home/Home.tsx (1)

42-52: LGTM! Consistent styling refinements.

The spacing adjustments (mb-2, tw-mb-0) and the styled span wrapper for the "View Collection" link follow the same Tailwind utility pattern applied in components/latest-activity/ActivityHeader.tsx, ensuring visual consistency across components.

__tests__/hooks/useActivityFilters.test.ts (2)

275-276: LGTM! Test assertions correctly updated for new enum values.

The updated expected strings ("All Transactions", "All Collections", "The Memes") align with the enum changes in hooks/useActivityData.ts, ensuring tests remain accurate.

Also applies to: 359-360, 559-572


283-306: Static analysis hint is a false positive.

The nesting depth warnings at lines 285 and 369 are typical for Jest test patterns where callbacks are verified inside act blocks. This structure is standard and acceptable for test code.

Also applies to: 367-389

__tests__/components/latest-activity/ActivityHeader.test.tsx (1)

39-44: LGTM! Test correctly verifies the new styled span wrapper.

The test assertions properly check for the span element with Tailwind utility classes (tw-whitespace-nowrap, tw-text-sm, tw-font-semibold), matching the component refactor in components/latest-activity/ActivityHeader.tsx.

components/latest-activity/ActivityHeader.tsx (1)

20-28: LGTM! Consistent migration to Tailwind utility classes.

The spacing utilities (tw-py-2, tw-mb-0) and styled span wrapper align with the broader styling refactor across components, eliminating SCSS module dependencies in favor of Tailwind.

components/meme-calendar/meme-calendar.helpers.tsx (2)

846-851: LGTM! SeasonMintRow now includes seasonIndex.

The seasonIndex field is computed once at line 890 and consistently assigned to all rows at line 900, ensuring correct season tracking across mint rows.

Also applies to: 890-890, 900-900


939-963: No changes needed—loop termination is safe and adequate for current usage.

The function limits iteration to 5 seasons (current + 4 ahead), providing approximately 120–135 mint rows in typical cases (3 mint days per week across 2-month seasons). This exceeds the observed minCount values of 50 or memes_subscriptions.length in both call sites. If insufficient rows exist across all 5 seasons, the function gracefully returns fewer rows than requested via result.slice(0, minCount), which is expected behavior.

hooks/useActivityData.ts (1)

12-26: LGTM! Enum values updated for improved UI clarity.

The enum label changes ("All Transactions", "All Collections", "The Memes") enhance user-facing text readability. The new UseActivityDataReturn interface formalizes the hook's public API. All related tests and components have been updated consistently.

Also applies to: 28-39

components/meme-calendar/MemeCalendarOverview.tsx (2)

416-461: LGTM! Season rollover logic is well-structured.

The refactored useMemo correctly handles the edge case where the current season only contains the canonical next mint. By fetching the next season's data when filteredRows is empty but containsCanonical is true, users will see meaningful upcoming mint data instead of an empty list.


469-470: Verify the UI text distinction is clear to users.

The conditional text "Upcoming SZN" vs "Upcoming Mints for SZN" creates different messaging based on isNextSeason. Ensure this distinction is intentional and provides clear context to users about whether they're viewing current or next season data.

components/utils/select/CommonSelect.tsx (1)

36-36: LGTM! New optional prop follows existing patterns.

The showFilterLabel prop is correctly declared as optional and integrates well with the existing prop interface structure.

components/utils/select/dropdown/CommonDropdown.tsx (1)

135-138: LGTM! Conditional label rendering is clean and accessible.

The implementation correctly:

  • Defaults showFilterLabel to false for backward compatibility
  • Renders the filter label before the computed label when enabled
  • Maintains accessibility via the existing aria-label attribute
__tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.toggle.test.tsx (2)

14-21: LGTM! Mock data correctly includes seasonIndex.

The mock row structure aligns with the updated SeasonMintRow interface that now includes seasonIndex.


23-29: LGTM! Mocks correctly updated for new helper API.

The mock now provides getUpcomingMintsAcrossSeasons and displayedSeasonNumberFromIndex, aligning with the refactored data retrieval approach used in the component.

components/subscriptions-report/SubscriptionsReport.tsx (2)

70-73: LGTM! Cross-season data retrieval with sensible fallback.

The use of upcomingCounts.length || 50 provides a reasonable default when the counts haven't loaded yet, ensuring the rows are available for rendering.


310-312: LGTM! Consistent season labeling format.

The "SZN {number} / {date}" format provides clear context for users about which season the upcoming drop belongs to.

components/user/subscriptions/UserPageSubscriptionsUpcoming.tsx (3)

55-58: LGTM! Data retrieval aligns with subscription count.

Using props.memes_subscriptions.length as the minCount ensures we fetch exactly as many rows as needed for the subscriptions being displayed.


197-224: LGTM! Season labeling is clear and consistent.

The updated UI with "SZN{number}" prefix and " / " separator provides a cleaner, more consistent format that aligns with the SubscriptionsReport component.


71-83: [Rewritten review comment]
[Classification tag]

Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
components/user/collected/filters/UserPageCollectedFilters.tsx (1)

60-103: Fix react-hooks/exhaustive-deps violation: checkScroll missing from dependency arrays

checkScroll is recreated each render and captured by both Effects but not included in their dependency arrays. Wrap with useCallback and add to deps.

-import { RefObject, useEffect, useRef, useState } from "react";
+import { RefObject, useCallback, useEffect, useRef, useState } from "react";

-  const checkScroll = () => {
+  const checkScroll = useCallback(() => {
     const container = scrollContainerRef.current;
     if (!container) return;

@@
     setCanScrollLeft(scrollLeft > 0);
     setCanScrollRight(scrollLeft < scrollWidth - clientWidth - 1);
-  };
+  }, []);

   useEffect(() => {
@@
-  }, []);
+  }, [checkScroll]);

   useEffect(() => {
@@
-  }, [filters.collection]);
+  }, [filters.collection, checkScroll]);
components/user/collected/UserPageCollected.tsx (1)

161-196: Season selection desynchronizes after URL updates: getFilters always returns szn: null

When a user selects a season, setSzn updates the local state and then calls updateFields to write szn=<id> to the URL. However, the URL change triggers the useEffect (line 393–396) which calls setFilters(getFilters()). Since getFilters hardcodes szn: null at line 182, this immediately overwrites the user's selection, causing SeasonsGridDropdown to fall back to "All Seasons" even though the URL still contains the season id.

The proposed fix preserves prev.szn if it matches the parsed initialSznId from the URL:

-useEffect(
-  () => setFilters(getFilters()),
-  [searchParams, profile, user, connectedAddress, getFilters]
-);
+useEffect(() => {
+  const next = getFilters();
+  setFilters((prev) => ({
+    ...next,
+    szn:
+      prev.szn && prev.szn.id === next.initialSznId
+        ? prev.szn
+        : next.szn,
+  }));
+}, [searchParams, profile, user, connectedAddress, getFilters]);

Longer-term: store sznId: number | null as the source of truth in filters and resolve it to the full MemeSeason object from the fetched seasons list when needed.

__tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx (1)

154-181: Mock profile has fields not in ApiIdentity interface.

The mockProfile includes wallet, pfp_url fields at lines 158 and 161 which are not in the ApiIdentity interface per the relevant code snippets. The interface has primary_wallet instead of wallet, and pfp instead of pfp_url. The as unknown as ApiIdentity cast hides these mismatches.

Consider aligning the mock with the actual interface:

 const mockProfile: ApiIdentity = {
   id: "1",
   handle: "testuser",
   normalised_handle: "testuser",
-  wallet: "0x123",
   display: "Test User",
   pfp: null,
-  pfp_url: null,
   cic: 0,
🧹 Nitpick comments (9)
__tests__/components/latest-activity/ActivityFilters.test.tsx (1)

271-307: Solid accessibility test coverage.

Testing aria-haspopup, aria-expanded state changes, and menuitem roles validates that CommonDropdown implements proper ARIA semantics. The assertion menuItems.length === Object.values(ContractFilter).length at line 306 ensures all options are accessible.

Consider adding a keyboard navigation test in a follow-up to verify users can navigate dropdown options with arrow keys and select with Enter, which would strengthen accessibility coverage:

it("supports keyboard navigation", async () => {
  const user = userEvent.setup();
  render(<ActivityFilters {...mockProps} />);
  
  const contractButton = screen.getByRole("button", {
    name: `Collection: ${ContractFilter.ALL}`,
  });
  
  await user.tab();
  expect(contractButton).toHaveFocus();
  
  await user.keyboard("{Enter}");
  expect(contractButton).toHaveAttribute("aria-expanded", "true");
});
components/user/collected/cards/UserPageCollectedCardsNoCards.tsx (1)

13-44: Remove derived-state useEffect/useState for msg
msg is fully derived from filters, so storing it in state + syncing via effect is unnecessary (and can complicate debugging).

-import { useEffect, useState } from "react";
+import { useMemo } from "react";
@@
-  const [msg, setMsg] = useState(getMsg());
-
-  useEffect(() => {
-    setMsg(getMsg());
-  }, [filters]);
+  const msg = useMemo(getMsg, [filters]);
components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx (1)

25-33: Avoid derived-state isMobile + effect; compute directly from breakpoint
No need to mirror breakpoint into local state here.

-  const getIsMobile = () => breakpoint !== "LG";
-  const [isMobile, setIsMobile] = useState<boolean>(false);
-
-  useEffect(() => {
-    setIsMobile(getIsMobile());
-  }, [breakpoint]);
+  const isMobile = breakpoint !== "LG";
components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx (1)

16-27: buttonPosition is typed but ignored
Prop type includes buttonPosition?: { right: number } but it’s not destructured/used. Either remove it from the type here, or wire it into positioning to avoid misleading call sites.

components/utils/select/dropdown/SeasonsGridDropdown.tsx (1)

68-78: Avoid empty catch in getButtonPosition (and likely unnecessary try/catch)
getBoundingClientRect() shouldn’t throw in normal cases; prefer simple guards. If you keep a catch, log context.

__tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx (1)

1-4: Drop React import if the repo uses the modern JSX transform
This test doesn’t use React.*; if your TS/Jest setup is on the automatic runtime, import React from "react"; can be removed.

components/utils/select/dropdown/SeasonsGridDropdownMobileWrapper.tsx (1)

59-72: Consider using FontAwesome for the close icon.

The component uses an inline SVG for the close button. Per coding guidelines, FontAwesome should be used for icons in React components. Consider replacing with faXmark or faTimes from FontAwesome for consistency across the codebase.

+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faXmark } from "@fortawesome/free-solid-svg-icons";
-                        <svg
-                          className="tw-w-6 tw-h-6 tw-flex-shrink-0 tw-text-white"
-                          viewBox="0 0 24 24"
-                          fill="none"
-                          aria-hidden="true"
-                          xmlns="http://www.w3.org/2000/svg">
-                          <path
-                            d="M18 6L6 18M6 6L18 18"
-                            stroke="currentColor"
-                            strokeWidth="2"
-                            strokeLinecap="round"
-                            strokeLinejoin="round"
-                          />
-                        </svg>
+                        <FontAwesomeIcon
+                          icon={faXmark}
+                          className="tw-w-6 tw-h-6 tw-flex-shrink-0 tw-text-white"
+                          aria-hidden="true"
+                        />
__tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx (1)

169-180: Test does not effectively verify subscription toggle state.

The test acknowledges in comments that subscription toggles may not render correctly in the test setup. Consider either fixing the mock setup to properly render toggles or removing/renaming this test to avoid false confidence.

__tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx (1)

348-349: Avoid arbitrary setTimeout in tests.

Using setTimeout with a fixed delay (line 348) can lead to flaky tests. Consider using waitFor or findBy* queries instead, which automatically retry until the condition is met or timeout.

-      await new Promise((resolve) => setTimeout(resolve, 0));
+    });
+
+    await waitFor(() => {
+      expect(screen.getByLabelText("Scroll filters left")).toBeInTheDocument();
     });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0777a6c and 2b83219.

📒 Files selected for processing (15)
  • __tests__/components/latest-activity/ActivityFilters.test.tsx (4 hunks)
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx (1 hunks)
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx (12 hunks)
  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx (1 hunks)
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx (3 hunks)
  • components/the-memes/TheMemes.tsx (8 hunks)
  • components/user/collected/UserPageCollected.tsx (6 hunks)
  • components/user/collected/cards/UserPageCollectedCardsNoCards.tsx (2 hunks)
  • components/user/collected/filters/UserPageCollectedFilters.tsx (6 hunks)
  • components/user/collected/filters/UserPageCollectedFiltersSzn.tsx (1 hunks)
  • components/utils/select/dropdown/SeasonsGridDropdown.tsx (1 hunks)
  • components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx (1 hunks)
  • components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx (1 hunks)
  • components/utils/select/dropdown/SeasonsGridDropdownMobileWrapper.tsx (1 hunks)
  • enums.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • enums.ts
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version

**/*.{ts,tsx,js,jsx}: Replace <img> elements with <Image /> from next/image to satisfy @next/next/no-img-element ESLint rule
Use <Link href="/path"> from Next.js for internal navigation instead of plain HTML links to satisfy @next/next/no-html-link-for-pages ESLint rule

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • components/user/collected/cards/UserPageCollectedCardsNoCards.tsx
  • components/user/collected/filters/UserPageCollectedFiltersSzn.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownMobileWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdown.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/the-memes/TheMemes.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • components/user/collected/UserPageCollected.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
  • components/user/collected/filters/UserPageCollectedFilters.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always add readonly before props in React components

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • components/user/collected/cards/UserPageCollectedCardsNoCards.tsx
  • components/user/collected/filters/UserPageCollectedFiltersSzn.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownMobileWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdown.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/the-memes/TheMemes.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • components/user/collected/UserPageCollected.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
  • components/user/collected/filters/UserPageCollectedFilters.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use <Link>, images should use next/image, and adopt Next's ESLint rules (Core Web Vitals)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • components/user/collected/cards/UserPageCollectedCardsNoCards.tsx
  • components/user/collected/filters/UserPageCollectedFiltersSzn.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownMobileWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdown.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/the-memes/TheMemes.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • components/user/collected/UserPageCollected.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
  • components/user/collected/filters/UserPageCollectedFilters.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Must pass tsc --noEmit type checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") over React. namespace usage (React.useMemo, React.useRef, etc.)
If the react-hooks/exhaustive-deps lint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic in useEffectEvent

**/*.{ts,tsx}: Must pass tsc --noEmit for TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
Use useEffectEvent for non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs: <Link> for internal links, next/image for images, adopt Next's ESLint rules
Use 'use cache' directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace <img> elements with <Image /> from next/image
Use <Link href="/path"> for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with 'use server' directive

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • components/user/collected/cards/UserPageCollectedCardsNoCards.tsx
  • components/user/collected/filters/UserPageCollectedFiltersSzn.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownMobileWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdown.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/the-memes/TheMemes.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • components/user/collected/UserPageCollected.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
  • components/user/collected/filters/UserPageCollectedFilters.tsx
**/@(__tests__|*.test).{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Tests should live in __tests__/ or ComponentName.test.tsx; mock external dependencies and APIs in tests

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Place tests in __tests__/ directory or as ComponentName.test.tsx alongside components

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Mock external dependencies and APIs in tests

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
__tests__/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use Jest + ts-jest for TypeScript testing

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
__tests__/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (tests/AGENTS.md)

__tests__/**/*.{ts,tsx,js}: Prefer for...of loops over forEach as it allows break/continue and works with async/await
Use array.at(-1) and array.at(-2) instead of index-based array access for negative indexing
Use String.prototype.replaceAll() instead of replace() for global string replacements
Use globalThis.fetch() instead of direct fetch() calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Use element.remove() instead of parent.removeChild(element) for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use semantic HTML elements (<label>, <output>) over ARIA attributes when possible; every form control must have a label

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
🧠 Learnings (13)
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Use testing-library/react + user-event for React component tests

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/@(__tests__|*.test).{ts,tsx} : Tests should live in `__tests__/` or `ComponentName.test.tsx`; mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/{components,contexts,hooks}/**/*.{ts,tsx} : Use semantic HTML elements (`<label>`, `<output>`) over ARIA attributes when possible; every form control must have a label

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • components/user/collected/cards/UserPageCollectedCardsNoCards.tsx
  • components/user/collected/filters/UserPageCollectedFiltersSzn.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/the-memes/TheMemes.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
  • components/user/collected/filters/UserPageCollectedFilters.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks

Applied to files:

  • components/utils/select/dropdown/SeasonsGridDropdown.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/the-memes/TheMemes.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: TypeScript + React functional components with hooks; follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Applied to files:

  • components/utils/select/dropdown/SeasonsGridDropdown.tsx
  • __tests__/components/latest-activity/ActivityFilters.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Test accessibility with keyboard navigation and screen reader compatibility

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Test high-risk areas including happy path workflows, invalid input errors, edge cases/boundaries, component & API interactions, and performance/security when relevant

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Use `element.remove()` instead of `parent.removeChild(element)` for DOM manipulation

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Prefer Server Components over Client Components; use Server Functions/Server Actions (`'use server'`) for mutations

Applied to files:

  • components/the-memes/TheMemes.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Keep tests independent, deterministic, and fast with production-like data

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
🧬 Code graph analysis (10)
__tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx (2)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
components/user/collected/filters/UserPageCollectedFiltersSzn.tsx (1)
  • UserPageCollectedFiltersSzn (5-26)
components/user/collected/filters/UserPageCollectedFiltersSzn.tsx (2)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
components/utils/select/dropdown/SeasonsGridDropdown.tsx (1)
  • SeasonsGridDropdown (17-175)
components/utils/select/dropdown/SeasonsGridDropdown.tsx (2)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx (1)
  • SeasonsGridDropdownItemsWrapper (10-54)
__tests__/components/latest-activity/ActivityFilters.test.tsx (2)
components/latest-activity/ActivityFilters.tsx (1)
  • ActivityFilters (15-51)
hooks/useActivityData.ts (1)
  • ContractFilter (128-128)
components/the-memes/TheMemes.tsx (3)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
constants.ts (1)
  • MEMES_CONTRACT (5-5)
components/utils/select/dropdown/SeasonsGridDropdown.tsx (1)
  • SeasonsGridDropdown (17-175)
components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx (2)
components/utils/select/dropdown/SeasonsGridDropdownMobileWrapper.tsx (1)
  • SeasonsGridDropdownMobileWrapper (4-100)
components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx (1)
  • SeasonsGridDropdownDesktopWrapper (16-114)
__tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx (2)
entities/ISubscription.ts (2)
  • NFTSubscription (16-21)
  • SubscriptionDetails (1-6)
components/meme-calendar/meme-calendar.helpers.tsx (1)
  • isMintingToday (524-526)
__tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx (2)
generated/models/ApiIdentity.ts (1)
  • ApiIdentity (17-185)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
__tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx (2)
components/user/collected/cards/UserPageCollectedCardsNoCards.tsx (1)
  • UserPageCollectedCardsNoCards (8-48)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
components/user/collected/filters/UserPageCollectedFilters.tsx (1)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (17)
__tests__/components/latest-activity/ActivityFilters.test.tsx (5)

1-20: Well-structured mocks for the new CommonDropdown-based UI.

The framer-motion mock correctly provides the animation hooks needed by CommonDropdown, and the Col mock preserves the grid props for testing. This aligns well with the component refactoring from native react-bootstrap dropdowns to CommonDropdown.


41-78: Excellent adoption of role-based queries.

Using getByRole("button", { name: /Collection:/i }) instead of data-testid makes tests more resilient and aligns with accessibility best practices. The template string assertions with enum values (e.g., Filter: ${TypeFilter.ALL}) ensure tests remain valid if enum values change.


115-139: Good use of for...of loops with proper cleanup.

Iterating through all enum values with for...of (per coding guidelines) and calling unmount() between iterations ensures comprehensive coverage without DOM pollution. This pattern reliably validates all possible prop values.


141-244: Comprehensive user interaction testing with proper async handling.

The tests correctly use userEvent.setup() and await interactions. Testing callback invocations with specific enum values (e.g., ContractFilter.MEMES, TypeFilter.SALES) validates the actual integration between CommonDropdown and the parent component. The exhaustive checks for all dropdown options using for...of loops ensure full coverage.


247-269: Good use of scoped queries with within().

Using within(col as HTMLElement) for scoped queries ensures the test validates the component's internal structure correctly. The rerender test with different isMobile values confirms component stability across prop changes.

components/user/collected/filters/UserPageCollectedFilters.tsx (1)

13-14: Good wiring for season entity + initialSeasonId propagation
Type change to MemeSeason | null and passing initialSeasonId={filters.initialSznId} looks consistent with the new SeasonsGridDropdown flow.

Also applies to: 51-52, 197-202

components/user/collected/filters/UserPageCollectedFiltersSzn.tsx (1)

1-25: Clean wrapper: props map 1:1 into SeasonsGridDropdown
selected, setSelected, initialSeasonId, and containerRef passthrough is straightforward.

__tests__/components/user/collected/filters/UserPageCollectedFiltersSzn.test.tsx (1)

8-46: Test intent is clear: verifies prop wiring into SeasonsGridDropdown
Mock + capturedProps assertions are straightforward for this wrapper component.

__tests__/components/user/collected/cards/UserPageCollectedCardsNoCards.test.tsx (1)

1-61: LGTM!

The test file correctly adopts the new MemeSeason type with a properly structured mockSeason object matching the interface definition. Test cases cover the key scenarios: seized filter active, no collection selected, memes with season, and gradients collection.

components/utils/select/dropdown/SeasonsGridDropdownMobileWrapper.tsx (1)

4-14: LGTM!

Props are correctly marked as readonly and typed appropriately. The component follows the controlled component pattern with isOpen and setOpen.

__tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx (2)

12-37: LGTM!

The mock data correctly includes the new seasonIndex field and uses consistent Date objects with UTC timestamps, aligning with the updated SeasonMintRow data shape.


82-84: Incomplete mock may cause issues if component uses other SubscriptionDetails fields.

The mockDetails object only contains profile but is cast to SubscriptionDetails. Per the interface definition, SubscriptionDetails has fields like consolidation_key, last_update, balance, and automatic. If the component accesses these fields, tests may pass incorrectly or fail unexpectedly.

Consider providing a more complete mock:

 const mockDetails: SubscriptionDetails = {
   profile: "testuser",
+  consolidation_key: "test-consolidation-key",
+  last_update: Date.now(),
+  balance: 100,
+  automatic: false,
 } as SubscriptionDetails;
components/the-memes/TheMemes.tsx (3)

104-106: LGTM!

State types correctly updated to use MemeSeason | null and number | null for the initial season ID, aligning with the entity-based season model.


273-279: Potential stale closure in getNftsNextPage reference.

The effect at lines 273-279 calls getNftsNextPage() which is defined at lines 165-172 and reads sort, sortDir, volumeType, and selectedSeason. However, getNftsNextPage is not in the dependency array, so if it's memoized or if there's a timing issue, the URL could be stale.

Since getNftsNextPage is a plain function defined in the component body, it will be recreated each render, so this should work correctly. The current approach is acceptable.


457-483: LGTM!

The SeasonsGridDropdown is correctly integrated for both desktop and mobile views with consistent props. The component handles its own season fetching and initial selection based on initialSeasonId.

__tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx (2)

183-195: LGTM!

The mockFilters object correctly uses MemeSeason | null for szn and includes the new initialSznId and handleOrWallet fields to match the updated filter shape.


425-482: LGTM!

Good practice verifying event listener cleanup on unmount. The test properly spies on both element and window listeners and restores spies after the test.

Comment thread components/utils/select/dropdown/SeasonsGridDropdown.tsx
Comment thread components/utils/select/dropdown/SeasonsGridDropdown.tsx Outdated
Comment thread components/utils/select/dropdown/SeasonsGridDropdown.tsx
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/user/collected/UserPageCollected.tsx (1)

161-195: Season filter can be dropped on initial load (URL has szn, but query ignores initialSznId). If a user loads /collected?...&szn=3, filters.szn stays null until a season object is resolved elsewhere, so the first API call can be unfiltered.

Suggested fix (use initialSznId as fallback for API params):

-      if (filters.szn) {
-        params.szn = filters.szn.id.toString();
-      }
+      const sznId = filters.szn?.id ?? filters.initialSznId;
+      if (sznId != null) {
+        params.szn = sznId.toString();
+      }

Also applies to: 424-426

🧹 Nitpick comments (9)
components/the-memes/TheMemes.tsx (1)

150-156: Use Number.isNaN instead of global isNaN.

The global isNaN performs type coercion which can lead to unexpected results. While it works correctly here since parsed is already a number, Number.isNaN is the modern best practice and avoids potential pitfalls.

     const routerSzn = searchParams?.get("szn");
     if (routerSzn) {
       const parsed = Number.parseInt(routerSzn);
-      if (!isNaN(parsed) && parsed > 0) {
+      if (!Number.isNaN(parsed) && parsed > 0) {
         initialSznId = parsed;
       }
     }
__tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx (3)

3-3: Consider using userEvent for more realistic user interactions.

The learnings recommend using @testing-library/user-event for React component tests. While fireEvent works, userEvent better simulates actual user behavior (e.g., click includes hover, focus, etc.).

Based on learnings, use testing-library/react + user-event for React component tests.

Apply this diff:

-import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
+import { render, screen, waitFor } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";

Then replace fireEvent.click(element) calls with await userEvent.click(element) throughout the tests (you can remove some of the act wrappers as userEvent handles async internally).


15-21: Consider typing mock function parameters.

The any types on lines 17 and 19 could be replaced with proper types for better type safety.

Apply this diff:

 jest.mock("framer-motion", () => ({
   useAnimate: () => [{ current: null }, jest.fn()],
-  AnimatePresence: ({ children }: any) => <>{children}</>,
+  AnimatePresence: ({ children }: { children?: React.ReactNode }) => <>{children}</>,
   motion: {
-    div: ({ children, ...props }: any) => <div {...props}>{children}</div>,
+    div: ({ children, ...props }: React.HTMLProps<HTMLDivElement>) => <div {...props}>{children}</div>,
   },
 }));

43-286: Add error handling and focus management tests.

Consider adding tests for:

  1. API error handling: The component has error handling logic that isn't tested.
  2. Focus management: After selecting an item, verify focus returns to the trigger button.

Example error handling test:

it("handles API error gracefully", async () => {
  const { commonApiFetch } = require("@/services/api/common-api");
  commonApiFetch.mockRejectedValueOnce(new Error("Network error"));
  
  const setSelected = jest.fn();
  const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation();
  
  render(<SeasonsGridDropdown selected={null} setSelected={setSelected} />);
  
  await waitFor(() => {
    expect(screen.getByRole("button", { name: /Season: All Seasons/i })).toBeInTheDocument();
  });
  
  expect(consoleErrorSpy).toHaveBeenCalledWith(
    "Failed to fetch meme seasons:",
    expect.any(Error)
  );
  
  consoleErrorSpy.mockRestore();
});

Example focus management test:

it("returns focus to trigger button after selection", async () => {
  const setSelected = jest.fn();
  const user = userEvent.setup();
  
  render(<SeasonsGridDropdown selected={null} setSelected={setSelected} />);
  
  const button = screen.getByRole("button", { name: /Season: All Seasons/i });
  await user.click(button);
  
  const szn1Button = screen.getByRole("menuitem", { name: /SZN 1/i });
  await user.click(szn1Button);
  
  await waitFor(() => {
    expect(button).toHaveFocus();
  });
});
__tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx (1)

150-167: Prefer user-event + for...of in tests (per repo test guidelines). This improves fidelity (pointer/keyboard semantics) and avoids forEach limitations.

Example tweak for the readonly assertion:

-    subscriptionToggles.forEach((toggle) => {
+    for (const toggle of subscriptionToggles) {
       expect(toggle).toBeDisabled();
-    });
+    }

Also applies to: 212-223

components/user/collected/UserPageCollected.tsx (1)

352-365: Keep filters.initialSznId in sync when a season is explicitly selected. Otherwise state can keep a stale “initial” season around (and makes the fallback logic ambiguous).

-  const setSzn = async (szn: MemeSeason | null): Promise<void> => {
-    setFilters((prev) => ({ ...prev, szn }));
+  const setSzn = async (szn: MemeSeason | null): Promise<void> => {
+    setFilters((prev) => ({ ...prev, szn, initialSznId: szn?.id ?? null }));
     const items: QueryUpdateInput[] = [
       {
         name: "szn",
         value: szn ? szn.id.toString() : null,
       },
__tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx (3)

75-93: Mock season should resemble MemeSeason to avoid accidental runtime coupling. Even if the mock is typed any, production code can start relying on other fields (e.g., name) and tests will silently become unrealistic.

-          <button onClick={() => setSelected({ id: 1, display: "SZN 1" })}>
+          <button
+            onClick={() =>
+              setSelected({
+                id: 1,
+                start_index: 1,
+                end_index: 100,
+                count: 100,
+                name: "Season 1",
+                display: "SZN 1",
+              })
+            }
+          >
             Season Filter
           </button>

290-302: Prefer user-event over fireEvent for clicks (repo test guideline).

Also applies to: 415-423


304-355: Brittle scroll-container selection + timer tick. Matching by Tailwind class substring and setTimeout(0) can make these tests flaky across refactors. Consider adding a stable test id in the component and replacing the timer tick with a microtask flush (or fake timers).

Example microtask flush:

-      await new Promise((resolve) => setTimeout(resolve, 0));
+      await Promise.resolve();

Also applies to: 357-423

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b83219 and 9db9336.

📒 Files selected for processing (12)
  • __tests__/components/seasons-dropdown/SeasonsDropdown.test.tsx (0 hunks)
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx (12 hunks)
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx (3 hunks)
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx (1 hunks)
  • components/latest-activity/ActivityFilters.tsx (2 hunks)
  • components/seasons-dropdown/SeasonsDropdown.module.scss (0 hunks)
  • components/seasons-dropdown/SeasonsDropdown.tsx (0 hunks)
  • components/the-memes/TheMemes.tsx (8 hunks)
  • components/user/collected/UserPageCollected.tsx (6 hunks)
  • components/utils/select/dropdown/SeasonsGridDropdown.tsx (1 hunks)
  • components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx (1 hunks)
  • components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx (1 hunks)
💤 Files with no reviewable changes (3)
  • components/seasons-dropdown/SeasonsDropdown.module.scss
  • components/seasons-dropdown/SeasonsDropdown.tsx
  • tests/components/seasons-dropdown/SeasonsDropdown.test.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • components/utils/select/dropdown/SeasonsGridDropdown.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownDesktopWrapper.tsx
  • components/utils/select/dropdown/SeasonsGridDropdownItemsWrapper.tsx
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version

**/*.{ts,tsx,js,jsx}: Replace <img> elements with <Image /> from next/image to satisfy @next/next/no-img-element ESLint rule
Use <Link href="/path"> from Next.js for internal navigation instead of plain HTML links to satisfy @next/next/no-html-link-for-pages ESLint rule

Files:

  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
  • components/user/collected/UserPageCollected.tsx
  • components/the-memes/TheMemes.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always add readonly before props in React components

Files:

  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
  • components/user/collected/UserPageCollected.tsx
  • components/the-memes/TheMemes.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use <Link>, images should use next/image, and adopt Next's ESLint rules (Core Web Vitals)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Files:

  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
  • components/user/collected/UserPageCollected.tsx
  • components/the-memes/TheMemes.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Must pass tsc --noEmit type checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") over React. namespace usage (React.useMemo, React.useRef, etc.)
If the react-hooks/exhaustive-deps lint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic in useEffectEvent

**/*.{ts,tsx}: Must pass tsc --noEmit for TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
Use useEffectEvent for non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs: <Link> for internal links, next/image for images, adopt Next's ESLint rules
Use 'use cache' directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace <img> elements with <Image /> from next/image
Use <Link href="/path"> for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with 'use server' directive

Files:

  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
  • components/user/collected/UserPageCollected.tsx
  • components/the-memes/TheMemes.tsx
**/@(__tests__|*.test).{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Tests should live in __tests__/ or ComponentName.test.tsx; mock external dependencies and APIs in tests

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Place tests in __tests__/ directory or as ComponentName.test.tsx alongside components

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Mock external dependencies and APIs in tests

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
__tests__/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use Jest + ts-jest for TypeScript testing

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
__tests__/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (tests/AGENTS.md)

__tests__/**/*.{ts,tsx,js}: Prefer for...of loops over forEach as it allows break/continue and works with async/await
Use array.at(-1) and array.at(-2) instead of index-based array access for negative indexing
Use String.prototype.replaceAll() instead of replace() for global string replacements
Use globalThis.fetch() instead of direct fetch() calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Use element.remove() instead of parent.removeChild(element) for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use semantic HTML elements (<label>, <output>) over ARIA attributes when possible; every form control must have a label

Files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
🧠 Learnings (16)
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions

Applied to files:

  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • components/user/collected/UserPageCollected.tsx
  • components/the-memes/TheMemes.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks

Applied to files:

  • components/latest-activity/ActivityFilters.tsx
  • components/the-memes/TheMemes.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: TypeScript + React functional components with hooks; follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Applied to files:

  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • components/the-memes/TheMemes.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Test high-risk areas including happy path workflows, invalid input errors, edge cases/boundaries, component & API interactions, and performance/security when relevant

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/@(__tests__|*.test).{ts,tsx} : Tests should live in `__tests__/` or `ComponentName.test.tsx`; mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Use testing-library/react + user-event for React component tests

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/{components,contexts,hooks}/**/*.{ts,tsx} : Use semantic HTML elements (`<label>`, `<output>`) over ARIA attributes when possible; every form control must have a label

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Keep tests independent, deterministic, and fast with production-like data

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx} : Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic

Applied to files:

  • __tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx
  • __tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Test accessibility with keyboard navigation and screen reader compatibility

Applied to files:

  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/__tests__/**/*.{ts,tsx} : Place tests in `__tests__/` directory or as `ComponentName.test.tsx` alongside components

Applied to files:

  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : All tests must live in `__tests__`, mirroring source folders (`components`, `contexts`, `hooks`, `utils`)

Applied to files:

  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Write tests following Arrange – Act – Assert pattern with one behaviour per test and clear, descriptive names

Applied to files:

  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Prefer Server Components over Client Components; use Server Functions/Server Actions (`'use server'`) for mutations

Applied to files:

  • components/the-memes/TheMemes.tsx
🧬 Code graph analysis (4)
__tests__/components/user/collected/filters/UserPageCollectedFilters.test.tsx (2)
generated/models/ApiIdentity.ts (1)
  • ApiIdentity (17-185)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
__tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx (2)
entities/ISubscription.ts (2)
  • NFTSubscription (16-21)
  • SubscriptionDetails (1-6)
components/meme-calendar/meme-calendar.helpers.tsx (1)
  • isMintingToday (524-526)
__tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx (2)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
components/utils/select/dropdown/SeasonsGridDropdown.tsx (1)
  • SeasonsGridDropdown (17-188)
components/user/collected/UserPageCollected.tsx (1)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
🪛 GitHub Check: SonarCloud Code Analysis
components/user/collected/UserPageCollected.tsx

[warning] 115-115: Prefer Number.isNaN over isNaN.

See more on https://sonarcloud.io/project/issues?id=6529-Collections_6529seize-frontend&issues=AZsSnKzT_lL1XmVo3Qpw&open=AZsSnKzT_lL1XmVo3Qpw&pullRequest=1645

components/the-memes/TheMemes.tsx

[warning] 153-153: Prefer Number.isNaN over isNaN.

See more on https://sonarcloud.io/project/issues?id=6529-Collections_6529seize-frontend&issues=AZsSnK3i_lL1XmVo3Qpz&open=AZsSnK3i_lL1XmVo3Qpz&pullRequest=1645

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
components/the-memes/TheMemes.tsx (6)

3-10: LGTM!

Import reorganization and additions for SeasonsGridDropdown and MemeSeason align with the component's migration to the new season selection UI.


104-105: LGTM!

Clean separation between the selected season object (MemeSeason | null) and the initial season ID from URL params. This allows SeasonsGridDropdown to resolve the full season object internally while the parent component just passes the initial ID.


165-172: LGTM!

Proper null-safe access to selectedSeason?.id for constructing the API query. The conditional filter construction is clean.


208-213: LGTM!

The URL construction correctly uses selectedSeason?.id. Including router in the dependency array satisfies exhaustive-deps. In Next.js App Router, useRouter returns a stable reference, so this won't cause unnecessary re-runs.


457-463: LGTM!

Clean integration of SeasonsGridDropdown with proper prop wiring. The component receives the selected season state, setter, and initial ID for URL-based initialization.


476-484: LGTM!

Mobile SeasonsGridDropdown mirrors the desktop implementation with consistent props, ensuring synchronized state across responsive breakpoints.

components/latest-activity/ActivityFilters.tsx (1)

43-62: Clean component structure and styling.

The component properly uses TailwindCSS for styling, conditionally adjusts layout based on isMobile, and correctly wires the CommonDropdown components with their respective callbacks. The "use client" directive is appropriate for this interactive filter UI.

__tests__/components/user/subscriptions/UserPageSubscriptionsUpcoming.test.tsx (2)

12-37: Mock rows look consistent with new seasonIndex shape.


39-52: The mock export name is correct and matches the actual helpers export. No mismatch exists. The actual function is displayedSeasonNumberFromIndex (verified at components/meme-calendar/meme-calendar.helpers.tsx:366), and the mock provides the correct name at line 51. All components consistently import and use this same name, so the test will not crash.

Likely an incorrect or invalid review comment.

Comment thread components/user/collected/UserPageCollected.tsx
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@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: 0

🧹 Nitpick comments (2)
components/user/collected/UserPageCollected.tsx (2)

424-426: Consider fallback to initialSznId.

As mentioned above, if filters.szn gets reset to null by the useEffect, this condition will be false and the szn parameter won't be sent to the API. Using filters.initialSznId as a fallback would ensure the filter is applied consistently.

       if (filters.szn) {
         params.szn = filters.szn.id.toString();
+      } else if (filters.initialSznId) {
+        params.szn = filters.initialSznId.toString();
       }

393-396: Consider preserving szn state across URL updates.

This useEffect replaces all filters with getFilters(), which always sets szn: null. When setSzn updates the URL, this effect runs and loses the szn object that was just set.

If the intent is to keep the full MemeSeason object in state, consider merging instead of replacing:

   useEffect(
-    () => setFilters(getFilters()),
+    () => setFilters((prev) => {
+      const newFilters = getFilters();
+      return { ...newFilters, szn: prev.szn };
+    }),
     [searchParams, profile, user, connectedAddress, getFilters]
   );

Alternatively, if the current behavior is intentional (relying on child components to re-initialize szn from initialSznId), then the query should use initialSznId as a fallback as suggested above.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9db9336 and d2280d5.

📒 Files selected for processing (2)
  • __tests__/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx (1 hunks)
  • components/user/collected/UserPageCollected.tsx (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/components/utils/select/dropdown/SeasonsGridDropdown.test.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version

**/*.{ts,tsx,js,jsx}: Replace <img> elements with <Image /> from next/image to satisfy @next/next/no-img-element ESLint rule
Use <Link href="/path"> from Next.js for internal navigation instead of plain HTML links to satisfy @next/next/no-html-link-for-pages ESLint rule

Files:

  • components/user/collected/UserPageCollected.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always add readonly before props in React components

Files:

  • components/user/collected/UserPageCollected.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use <Link>, images should use next/image, and adopt Next's ESLint rules (Core Web Vitals)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Files:

  • components/user/collected/UserPageCollected.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Must pass tsc --noEmit type checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") over React. namespace usage (React.useMemo, React.useRef, etc.)
If the react-hooks/exhaustive-deps lint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic in useEffectEvent

**/*.{ts,tsx}: Must pass tsc --noEmit for TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
Use useEffectEvent for non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs: <Link> for internal links, next/image for images, adopt Next's ESLint rules
Use 'use cache' directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace <img> elements with <Image /> from next/image
Use <Link href="/path"> for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with 'use server' directive

Files:

  • components/user/collected/UserPageCollected.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions

Applied to files:

  • components/user/collected/UserPageCollected.tsx
🧬 Code graph analysis (1)
components/user/collected/UserPageCollected.tsx (1)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
components/user/collected/UserPageCollected.tsx (6)

14-14: LGTM!

Import correctly added for the new MemeSeason type.


39-51: LGTM!

Interface properly updated with MemeSeason type and initialSznId for URL-derived initialization.


104-116: LGTM!

The issues from past review comments have been addressed—function now correctly uses Number.parseInt(szn, 10) with radix and Number.isNaN(parsed) for reliable NaN checking.


182-186: Verify state synchronization between szn and initialSznId.

szn is always initialized to null, relying on child components to populate it using initialSznId. However, when setSzn updates the URL, the useEffect at line 393-396 re-runs getFilters(), which resets szn back to null. This could cause the query at lines 424-426 to fire without the szn parameter after the state resets.

Consider using initialSznId directly in the query when filters.szn is null:

       if (filters.szn) {
-        params.szn = filters.szn.id.toString();
+        params.szn = filters.szn.id.toString();
+      } else if (filters.initialSznId) {
+        params.szn = filters.initialSznId.toString();
       }

Alternatively, preserve szn in the useEffect by merging instead of replacing.


187-187: LGTM!

Radix parameter correctly added to Number.parseInt.


352-365: LGTM!

The setSzn function correctly handles MemeSeason objects, updating local state immediately before the URL to ensure the query has access to the full object.

Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
components/the-memes/TheMemes.tsx (2)

450-467: Remove comments per coding guidelines.

The coding guidelines specify that code should be self-explanatory without comments. The structure and responsive CSS classes already indicate the layout breakpoints.

Apply this diff:

           <Container className="pt-4">
             <>
-              {/* Page header - visible on all devices */}
               <Row>
                 <Col className="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-3">
               </Row>

-              {/* Mobile & tablet elements - visible until xl breakpoint (1200px) */}
               <Row className="d-xl-none">
                 <Col xs={12} className="mb-3">

111-163: SeasonsGridDropdown doesn't re-apply season selection on URL changes during browser navigation.

When searchParams changes (e.g., browser back/forward), setInitialSeasonId() updates with the new value (line 161). However, SeasonsGridDropdown won't re-select the season because its initialApplied flag (line 28 of SeasonsGridDropdown.tsx) blocks re-application once set to true. This causes the displayed season to drift out of sync with the URL parameter.

The useEffect at lines 50–60 of SeasonsGridDropdown.tsx runs when initialSeasonId changes, but the early-return at line 52 (if (initialApplied) return;) prevents re-selection. Reset initialApplied when initialSeasonId changes, or track the previous value to apply only when it actually changes.

🧹 Nitpick comments (2)
components/the-memes/TheMemes.tsx (2)

165-172: Consider memoizing getNftsNextPage with useCallback.

While functionally correct (all closure dependencies are tracked in the consuming useEffect), wrapping this function in useCallback would satisfy the react-hooks/exhaustive-deps rule and align with modern React patterns.

Apply this refactor:

+import { useContext, useEffect, useState, useCallback } from "react";
+const getNftsNextPage = useCallback(() => {
   const mySort = getApiSort(sort, volumeType);
   let seasonFilter = "";
   if (selectedSeason) {
     seasonFilter = `&season=${selectedSeason.id}`;
   }
   return `${publicEnv.API_ENDPOINT}/api/memes_extended_data?page_size=48&sort_direction=${sortDir}&sort=${mySort}${seasonFilter}`;
+}, [sort, volumeType, selectedSeason, sortDir]);

257-271: Consider memoizing fetchNfts with useCallback.

Similar to getNftsNextPage, wrapping this function in useCallback would prevent potential exhaustive-deps warnings and follow React best practices.

Apply this refactor:

-function fetchNfts() {
+const fetchNfts = useCallback(() => {
   if (!nftsNextPage) {
     setFetching(false);
     return;
   }
   fetchUrl(nftsNextPage)
     .then((responseNfts: DBResponse) => {
       setNfts((prev) => [...prev, ...(responseNfts.data ?? [])]);
       setNftsNextPage(responseNfts.next);
     })
     .catch(() => {
       // optionally surface a toast/log here
     })
     .finally(() => setFetching(false));
-}
+}, [nftsNextPage]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d2280d5 and 491b261.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • components/the-memes/TheMemes.tsx (8 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version

**/*.{ts,tsx,js,jsx}: Replace <img> elements with <Image /> from next/image to satisfy @next/next/no-img-element ESLint rule
Use <Link href="/path"> from Next.js for internal navigation instead of plain HTML links to satisfy @next/next/no-html-link-for-pages ESLint rule

Files:

  • components/the-memes/TheMemes.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always add readonly before props in React components

Files:

  • components/the-memes/TheMemes.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use <Link>, images should use next/image, and adopt Next's ESLint rules (Core Web Vitals)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Files:

  • components/the-memes/TheMemes.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Must pass tsc --noEmit type checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") over React. namespace usage (React.useMemo, React.useRef, etc.)
If the react-hooks/exhaustive-deps lint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic in useEffectEvent

**/*.{ts,tsx}: Must pass tsc --noEmit for TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
Use useEffectEvent for non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs: <Link> for internal links, next/image for images, adopt Next's ESLint rules
Use 'use cache' directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace <img> elements with <Image /> from next/image
Use <Link href="/path"> for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with 'use server' directive

Files:

  • components/the-memes/TheMemes.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions

Applied to files:

  • components/the-memes/TheMemes.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Prefer Server Components over Client Components; use Server Functions/Server Actions (`'use server'`) for mutations

Applied to files:

  • components/the-memes/TheMemes.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks

Applied to files:

  • components/the-memes/TheMemes.tsx
🧬 Code graph analysis (1)
components/the-memes/TheMemes.tsx (2)
entities/ISeason.ts (1)
  • MemeSeason (1-8)
components/utils/select/dropdown/SeasonsGridDropdown.tsx (1)
  • SeasonsGridDropdown (17-188)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
components/the-memes/TheMemes.tsx (3)

104-105: LGTM: Type-safe season state management.

The migration from numeric season to MemeSeason | null with separate initialSeasonId tracking correctly separates URL-sourced initial values from user-driven state changes.


458-462: LGTM: SeasonsGridDropdown integration.

The dropdown component is correctly integrated in both desktop and mobile layouts with proper prop wiring for selected, setSelected, and initialSeasonId.

Also applies to: 478-482


188-213: LGTM: URL synchronization logic.

The useEffect correctly syncs the selected season to the URL query string with proper dependency tracking, maintaining unidirectional data flow from state to URL.

Signed-off-by: prxt6529 <prxt@6529.io>
@sonarqubecloud
Copy link
Copy Markdown

@prxt6529 prxt6529 merged commit 3cad4d8 into main Dec 12, 2025
9 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Mar 11, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Apr 2, 2026
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.

3 participants