Skip to content

Wave outcomes fix#1698

Merged
simo6529 merged 3 commits intomainfrom
wave-outcomes-fix
Jan 5, 2026
Merged

Wave outcomes fix#1698
simo6529 merged 3 commits intomainfrom
wave-outcomes-fix

Conversation

@simo6529
Copy link
Copy Markdown
Collaborator

@simo6529 simo6529 commented Jan 5, 2026

Summary by CodeRabbit

  • Refactor
    • Consolidated reward calculation to present NIC, Rep, and Manual totals rather than per-item lists.
    • Simplified and narrowed component interfaces to reduce internal dependencies.
    • Reorganized layout and class structure for winner/podium views and fullscreen modal for improved alignment and responsiveness.
    • Propagated updated voting state handling so vote controls and summaries reflect end/visibility status.

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

Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 5, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Rewires outcome calculation by removing the legacy useDropOutcomes hook and Wave prop propagation, replacing per-drop outcomes with useWaveRankReward totals (nicTotal, repTotal, manualOutcomes). Updates winner/drop components and outcome type discriminants to use ApiWaveOutcome* constants and adjusts layout/classNames.

Changes

Cohort / File(s) Summary
Hook Removal & Replacement
hooks/drops/useDropOutcomes.tsx, hooks/waves/useWaveRankReward.ts
Deleted useDropOutcomes (OutcomeType enum and related interfaces). useWaveRankReward index lookup adjusted from d.index === targetIndex to d.index - 1 === targetIndex.
Drop Info Panel
components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
Replaced manual outcomes calculation with useWaveRankReward (enabled: true); removed calculateOutcomes and ApiWaveOutcome imports; layout and className reorganizations; propagated voting state flags through vote summary.
Winner Small Components
components/waves/winners/DefaultWaveWinnerDropSmall.tsx, components/waves/winners/MemesWaveWinnerDropSmall.tsx, components/waves/winners/WaveWinnerItemSmall.tsx
Removed wave: ApiWave prop from child usage and component props where applicable; parent no longer forwards wave to children; minor className/layout tweaks.
Outcome Display Migration
components/waves/winners/WaveWinnersSmallOutcome.tsx
Removed wave prop and ApiWave usage; replaced per-outcome lists with totals from useWaveRankReward (nicTotal, repTotal, manualOutcomes); tooltip and outcome rendering simplified; new SVG icons added.
Outcome Type Constant Updates
components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx, components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx
Replaced local OutcomeType discriminants with ApiWaveOutcomeCredit / ApiWaveOutcomeType constants (NIC → Cic, REP → Rep, MANUAL → Manual).

Sequence Diagram(s)

(Skipped — changes are refactor/data-source swaps without a new multi-component sequential flow that benefits from a diagram.)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • #1672 — Migrates outcome calculation to useWaveRankReward and removes useDropOutcomes dependency across outcome components.
  • #1655 — Overlaps changes to MemesSingleWaveDropInfoPanel and outcome hook/component updates.
  • #1670 — Related modifications to how wave outcomes are represented/consumed in winner components.

Suggested reviewers

  • ragnep
  • GelatoGenesis
  • prxt6529

Poem

🐰 I nibbled through hooks in the night,
Rewrote the hops to make outcomes light.
Props trimmed down, totals now sing,
Nic, Rep, Manual — a cleaner spring.
Hooray — a tidy rabbit's delight! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Wave outcomes fix' is vague and generic, lacking specific information about what aspect of wave outcomes is being fixed or changed. Consider a more descriptive title that specifies the nature of the fix, such as 'Replace useDropOutcomes with useWaveRankReward hook' or 'Refactor wave outcomes calculation to use rank-based rewards'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a127be9 and 4b2a96f.

📒 Files selected for processing (1)
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx

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

Fix all issues with AI Agents 🤖
In @components/waves/drop/MemesSingleWaveDropInfoPanel.tsx:
- Line 48: Remove the debug console.log in the MemesSingleWaveDropInfoPanel
component: delete the line that logs { nicTotal, repTotal, manualOutcomes } (or
replace it with a proper logger that is disabled in production), ensuring the
component no longer emits console output in production builds.
🧹 Nitpick comments (1)
components/waves/winners/WaveWinnersSmallOutcome.tsx (1)

46-94: Consider conditionally rendering NIC and Rep sections in the tooltip.

The NIC and Rep sections are always rendered in the tooltip content, but the button icons are conditionally rendered based on !!nicTotal and !!repTotal. This could display "NIC: 0" or "Rep: 0" in the tooltip when those outcome types don't exist for this rank.

🔎 Proposed fix to conditionally render tooltip sections
         <div className="tw-space-y-2">
+          {!!nicTotal && (
           <div className="tw-flex tw-items-center tw-justify-between tw-rounded-lg tw-bg-iron-800/40 tw-p-2">
             <div className="tw-flex tw-items-center tw-gap-2">
               <svg
                 className="tw-size-4 tw-flex-shrink-0 tw-text-[#A4C2DB]"
                 viewBox="0 0 24 24"
                 aria-hidden="true"
                 fill="none"
               >
                 <path
                   d="M9 6.75H15M9 12H15M9 17.25H12M3.75 19.5H20.25C21.0784 19.5 21.75 18.8284 21.75 18V6C21.75 5.17157 21.0784 4.5 20.25 4.5H3.75C2.92157 4.5 2.25 5.17157 2.25 6V18C2.25 18.8284 2.92157 19.5 3.75 19.5Z"
                   stroke="currentColor"
                   strokeWidth="1.5"
                   strokeLinecap="round"
                   strokeLinejoin="round"
                 />
               </svg>
               <span className="tw-text-sm tw-font-medium tw-text-iron-200">
                 NIC
               </span>
             </div>
             <span className="tw-text-sm tw-font-semibold tw-text-[#A4C2DB]">
               {formatNumberWithCommas(nicTotal)}
             </span>
           </div>
+          )}

+          {!!repTotal && (
           <div className="tw-flex tw-flex-col tw-gap-y-1 tw-rounded-lg tw-bg-iron-800/40 tw-p-2">
             <div className="tw-flex tw-items-center tw-justify-between">
               <div className="tw-flex tw-items-center tw-gap-2">
                 <svg
                   className="tw-size-4 tw-flex-shrink-0 tw-text-[#C3B5D9]"
                   viewBox="0 0 24 24"
                   aria-hidden="true"
                   fill="none"
                 >
                   <path
                     d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z"
                     stroke="currentColor"
                     strokeWidth="1.5"
                   />
                 </svg>
                 <span className="tw-text-sm tw-font-medium tw-text-iron-200">
                   Rep
                 </span>
               </div>
               <span className="tw-text-sm tw-font-semibold tw-text-[#C3B5D9]">
                 {formatNumberWithCommas(repTotal)}
               </span>
             </div>
           </div>
+          )}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 839f17b and a127be9.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/winners/DefaultWaveWinnerDropSmall.tsx
  • components/waves/winners/MemesWaveWinnerDropSmall.tsx
  • components/waves/winners/WaveWinnerItemSmall.tsx
  • components/waves/winners/WaveWinnersSmallOutcome.tsx
  • components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx
  • components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx
  • hooks/drops/useDropOutcomes.tsx
  • hooks/waves/useWaveRankReward.ts
💤 Files with no reviewable changes (2)
  • hooks/drops/useDropOutcomes.tsx
  • components/waves/winners/WaveWinnerItemSmall.tsx
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{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}: Remove unnecessary Effects. If the Effect's only job is to derive or sync internal state, calculate during render or use useMemo instead.
Use useEffectEvent for non-reactive logic inside Effects to read the latest props/state without turning them into dependencies or causing unnecessary re-runs.
Use explicit caching with "use cache" directive at the top of Server Components, routes, or functions. Configure cacheComponents: true in next.config.ts as needed.

**/*.{ts,tsx,js,jsx}: Remove unnecessary Effects; if the Effect only derives state, compute during render instead
Use useEffectEvent when listening to external events but needing the latest props/state without re-running the Effect
Move data fetching from client Effects to Server Components; mutations go through Server Actions ('use server')

Files:

  • components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx
  • components/waves/winners/MemesWaveWinnerDropSmall.tsx
  • components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx
  • components/waves/winners/DefaultWaveWinnerDropSmall.tsx
  • hooks/waves/useWaveRankReward.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/winners/WaveWinnersSmallOutcome.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

**/*.{tsx,jsx}: Use internal links via <Link> component from Next.js instead of <a> tags
Replace <img> elements with <Image /> from next/image

Files:

  • components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx
  • components/waves/winners/MemesWaveWinnerDropSmall.tsx
  • components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx
  • components/waves/winners/DefaultWaveWinnerDropSmall.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/winners/WaveWinnersSmallOutcome.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Run npm run lint to ensure code satisfies ESLint (Next's Core Web Vitals + React Hooks). Code must pass linting before completing any task.

**/*.{js,ts,jsx,tsx}: Code must satisfy ESLint with Next's Core Web Vitals and React Hooks rules by running npm run lint
Do not add eslint-disable comments unless explicitly instructed; prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions

Files:

  • components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx
  • components/waves/winners/MemesWaveWinnerDropSmall.tsx
  • components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx
  • components/waves/winners/DefaultWaveWinnerDropSmall.tsx
  • hooks/waves/useWaveRankReward.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/winners/WaveWinnersSmallOutcome.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

Files:

  • components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx
  • components/waves/winners/MemesWaveWinnerDropSmall.tsx
  • components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx
  • components/waves/winners/DefaultWaveWinnerDropSmall.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/winners/WaveWinnersSmallOutcome.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Use TypeScript with React functional components and hooks. Follow existing code style and naming conventions.

Files:

  • components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx
  • components/waves/winners/MemesWaveWinnerDropSmall.tsx
  • components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx
  • components/waves/winners/DefaultWaveWinnerDropSmall.tsx
  • hooks/waves/useWaveRankReward.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/winners/WaveWinnersSmallOutcome.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx
  • components/waves/winners/MemesWaveWinnerDropSmall.tsx
  • components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx
  • components/waves/winners/DefaultWaveWinnerDropSmall.tsx
  • hooks/waves/useWaveRankReward.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/winners/WaveWinnersSmallOutcome.tsx
**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer direct named imports from React (useMemo, useRef, FC) over React. namespace usage

Files:

  • components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx
  • components/waves/winners/MemesWaveWinnerDropSmall.tsx
  • components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx
  • components/waves/winners/DefaultWaveWinnerDropSmall.tsx
  • hooks/waves/useWaveRankReward.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/winners/WaveWinnersSmallOutcome.tsx
**/*.{ts,js}

📄 CodeRabbit inference engine (AGENTS.md)

When parsing Seize URLs or similar, fail fast if base origin is unavailable instead of falling back to placeholder origins

Files:

  • hooks/waves/useWaveRankReward.ts
🧠 Learnings (2)
📚 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 FontAwesome for icons in React components

Applied to files:

  • components/waves/winners/drops/header/WaveWinnersDropOutcome.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
Learning: Applies to __tests__/**/*.{ts,tsx,js},!**/__tests__/**,!**/__mocks__/**,!**/*.d.ts : Use `Array.at()` method for negative indexing instead of `array[array.length - n]`

Applied to files:

  • hooks/waves/useWaveRankReward.ts
🧬 Code graph analysis (2)
components/waves/winners/DefaultWaveWinnerDropSmall.tsx (1)
components/waves/winners/WaveWinnersSmallOutcome.tsx (1)
  • WaveWinnersSmallOutcome (13-200)
components/waves/winners/WaveWinnersSmallOutcome.tsx (3)
helpers/waves/drop.helpers.ts (1)
  • ExtendedDrop (16-20)
hooks/waves/useWaveRankReward.ts (1)
  • useWaveRankReward (18-96)
helpers/Helpers.ts (1)
  • formatNumberWithCommas (131-148)
⏰ 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/waves/winners/drops/header/WaveWinnersDropOutcome.tsx (1)

17-49: LGTM!

The migration from local OutcomeType enum to ApiWaveOutcomeCredit and ApiWaveOutcomeType constants is clean. Using API-generated types ensures consistency with the backend contract and eliminates potential enum drift.

components/waves/winners/podium/WavePodiumItemContentOutcomes.tsx (1)

41-67: LGTM!

The type discriminant migration to ApiWaveOutcomeCredit and ApiWaveOutcomeType is consistent with the PR's refactoring approach. The useMemo correctly memoizes the award transformation.

components/waves/winners/MemesWaveWinnerDropSmall.tsx (2)

22-23: LGTM!

The removal of the wave prop from the component signature aligns with the PR's refactoring to derive outcome data from drop.wave.id via the useWaveRankReward hook instead.


158-160: LGTM!

The WaveWinnersSmallOutcome component now correctly receives only the drop prop, which contains the necessary wave.id and rank for the internal useWaveRankReward hook.

components/waves/drop/MemesSingleWaveDropInfoPanel.tsx (1)

42-46: LGTM!

The integration of useWaveRankReward correctly derives outcome totals from the drop's wave ID and rank, replacing the previous manual calculation approach.

components/waves/winners/DefaultWaveWinnerDropSmall.tsx (2)

22-23: LGTM!

The removal of the wave prop is consistent with the refactoring pattern applied across the winner components in this PR.


158-159: LGTM!

The WaveWinnersSmallOutcome component usage is correctly updated to pass only the drop prop.

components/waves/winners/WaveWinnersSmallOutcome.tsx (1)

30-33: LGTM!

The hook integration correctly derives outcome data from the drop's embedded wave information, eliminating the need for a separate wave prop.

hooks/waves/useWaveRankReward.ts (1)

72-88: Verify the API index contract for distribution items.

The index comparison changed from d.index === targetIndex to d.index - 1 === targetIndex. This shift changes the expected API index semantics from 0-based to 1-based: the code now matches items where d.index === rank instead of d.index === rank - 1. Confirm this aligns with the backend API's actual index semantics, as this is a breaking behavioral change if incorrect.

Comment thread components/waves/drop/MemesSingleWaveDropInfoPanel.tsx Outdated
Signed-off-by: Simo <simo@6529.io>
@simo6529 simo6529 merged commit 4098cc3 into main Jan 5, 2026
6 of 7 checks passed
@simo6529 simo6529 deleted the wave-outcomes-fix branch January 5, 2026 10:00
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Jan 5, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
12.5% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@coderabbitai coderabbitai Bot mentioned this pull request Jan 10, 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.

2 participants