Skip to content

Added title leaderboard grid card and improved ui#1635

Merged
ragnep merged 7 commits intomainfrom
leaderboard-grid-card-redesign
Dec 5, 2025
Merged

Added title leaderboard grid card and improved ui#1635
ragnep merged 7 commits intomainfrom
leaderboard-grid-card-redesign

Conversation

@ragnep
Copy link
Copy Markdown
Contributor

@ragnep ragnep commented Dec 5, 2025

Summary by CodeRabbit

  • New Features

    • Voting button adds an optional styling variant to choose between updated visual styles.
  • User Interface Updates

    • Button label shortened to "Vote" with refreshed shape, spacing, timing and hover/shadow behavior.
    • Vote progress visuals refreshed: arrow coloring, mono numeric font, adjusted spacing, and revamped tooltip look and positioning.
    • Leaderboard gallery layout refreshed: imagery-first presentation, refined spacing/typography, winner badge placement, and compact vote display.
  • Behavior Changes

    • Gallery animations and highlight timing reworked for more reliable, responsive transitions.

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

Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 5, 2025

Walkthrough

Refactors styling and behavior across vote-related UI: updates DropVoteProgressing tooltip and color/arrow handling, introduces variant styling and a new prop on VotingModalButton, and rewrites WaveLeaderboardGalleryItem animation/timer logic, layout, and vote UI placement. No exported function signatures except VotingModalButtonProps variant addition.

Changes

Cohort / File(s) Change Summary
Vote progress / Tooltip
components/drops/view/utils/DropVoteProgressing.tsx
Adds arrowColor; separates subtle vs non‑subtle styling; moves number color to a dynamic class; reduces FontAwesome icon size; rewrites tooltip to use offset, custom background/font/borderRadius, higher z-index, pointer-events disabled; simplifies tooltip content.
Voting button
components/voting/VotingModalButton.tsx
Adds optional variant prop to props; reworks base and variant utility classes (gap, rounded, transition/timing, hover/shadow); subtle/default visuals changed; label shortened from "Vote for this!" to "Vote".
Leaderboard gallery & votes
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx, components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx
Replaces useState flags with refs and timerRef; consolidates animation/cleanup and touch detection; updates container/image classes and hover scale; moves rank/badge rendering; relocates vote UI and adjusts vote typography and spacing; introduces getVoteStyle; subtle color handling simplified.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Focus review on:
    • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx — ref vs state logic, timer cleanup, effect dependencies, and layout changes.
    • components/drops/view/utils/DropVoteProgressing.tsx — tooltip positioning/styling changes and color/arrow handling.
    • components/voting/VotingModalButton.tsx — public prop addition and variant styling differences.

Suggested reviewers

  • simo6529

Poem

🐇 I hopped through classes late at night,
Tweaked arrows, fonts, and tooltip light.
Timers tucked, styles set just so,
A quiet hop — the UI’s glow. ✨

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 mentions 'leaderboard grid card' which aligns with changes to WaveLeaderboardGalleryItem, but it vaguely summarizes the full scope as 'improved ui' without clearly conveying the primary focus. Consider a more specific title like 'Redesign wave leaderboard gallery item layout and voting UI' to better capture the main changes across multiple components.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch leaderboard-grid-card-redesign

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.

Signed-off-by: ragnep <ragneinfo@gmail.com>
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

🧹 Nitpick comments (3)
components/voting/VotingModalButton.tsx (1)

27-32: Font weight utilities may conflict between base and subtle variants

baseClasses sets tw-font-medium while the subtle variant adds tw-font-bold. Because Tailwind resolves conflicts by CSS rule order (not class order), the subtle button may still render as medium weight instead of bold. To make the intent explicit and avoid relying on utility order, consider moving font weight out of the base classes and into the variants:

-  const baseClasses = "tw-flex tw-items-center tw-justify-center tw-gap-x-1 tw-px-3 tw-py-1.5 tw-rounded-lg tw-border tw-border-solid tw-text-xs tw-font-medium tw-whitespace-nowrap tw-transition-all tw-duration-300 tw-ease-out";
+  const baseClasses = "tw-flex tw-items-center tw-justify-center tw-gap-x-1 tw-px-3 tw-py-1.5 tw-rounded-lg tw-border tw-border-solid tw-text-xs tw-whitespace-nowrap tw-transition-all tw-duration-300 tw-ease-out";

-  const variantClasses = variant === "subtle"
-    ? "tw-bg-white tw-border-white tw-text-black tw-font-bold desktop-hover:hover:tw-bg-iron-300 tw-shadow-[0_0_15px_rgba(255,255,255,0.1)]"
-    : "tw-bg-primary-500 tw-border-primary-500 tw-text-white desktop-hover:hover:tw-bg-primary-600";
+  const variantClasses = variant === "subtle"
+    ? "tw-bg-white tw-border-white tw-text-black tw-font-bold desktop-hover:hover:tw-bg-iron-300 tw-shadow-[0_0_15px_rgba(255,255,255,0.1)]"
+    : "tw-bg-primary-500 tw-border-primary-500 tw-text-white tw-font-medium desktop-hover:hover:tw-bg-primary-600";

This keeps the default button medium-weight and makes the subtle variant reliably bold.

Also applies to: 37-37

components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx (1)

31-41: Simplify getColorClass to avoid dead subtle-branch logic

In the JSX, subtle mode bypasses getColorClass:

className={`tw-text-sm tw-font-mono tw-font-bold ${
  variant === 'subtle' ? 'tw-text-iron-100' : getColorClass()
}`}

But getColorClass itself also checks variant === 'subtle', which is now unreachable, adding noise. You can simplify and centralize the color decision:

-  const getColorClass = () => {
-    if (variant === 'subtle') {
-      // More subtle coloring that doesn't draw focus from the artwork
-      return isPositive 
-        ? "tw-text-iron-300" 
-        : "tw-text-iron-400";
-    }
-    // Original bright coloring
-    return isPositive ? "tw-text-emerald-500" : "tw-text-rose-500";
-  };
+  const getColorClass = () => {
+    if (variant === "subtle") {
+      // More subtle coloring that doesn't draw focus from the artwork
+      return "tw-text-iron-100";
+    }
+    // Original bright coloring
+    return isPositive ? "tw-text-emerald-500" : "tw-text-rose-500";
+  };
@@
-      <span
-        className={`tw-text-sm tw-font-mono tw-font-bold ${variant === 'subtle' ? 'tw-text-iron-100' : getColorClass()}`}
-      >
+      <span className={`tw-text-sm tw-font-mono tw-font-bold ${getColorClass()}`}>

This keeps current visuals (subtle = tw-text-iron-100, default = emerald/rose) and removes unused logic.

components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (1)

169-188: Consider migrating the inline SVG icon to FontAwesome over time

The rater-count icon is still an inline <svg> while other components (e.g., DropVoteProgressing) use FontAwesomeIcon. To keep iconography consistent and follow the “use FontAwesome for icons” guideline, you might eventually replace this with a corresponding FontAwesome glyph (e.g., users/people icon) wired through @fortawesome/react-fontawesome. This is non-blocking for the current PR.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f91f891 and 580376b.

📒 Files selected for processing (4)
  • components/drops/view/utils/DropVoteProgressing.tsx (1 hunks)
  • components/voting/VotingModalButton.tsx (1 hunks)
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (3 hunks)
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx (1 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/voting/VotingModalButton.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx
  • components/drops/view/utils/DropVoteProgressing.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/voting/VotingModalButton.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx
  • components/drops/view/utils/DropVoteProgressing.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/voting/VotingModalButton.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx
  • components/drops/view/utils/DropVoteProgressing.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/voting/VotingModalButton.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx
  • components/drops/view/utils/DropVoteProgressing.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-03T14:52:34.255Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.255Z
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/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx
  • components/drops/view/utils/DropVoteProgressing.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
📚 Learning: 2025-12-03T14:52:34.255Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.255Z
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/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.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 FontAwesome for icons in React components

Applied to files:

  • components/drops/view/utils/DropVoteProgressing.tsx
🧬 Code graph analysis (2)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx (2)
helpers/Helpers.ts (1)
  • formatNumberWithCommas (103-120)
components/drops/view/utils/DropVoteProgressing.tsx (1)
  • DropVoteProgressing (13-80)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (5)
hooks/useDeviceInfo.ts (1)
  • useDeviceInfo (23-93)
components/drops/view/item/content/media/MediaDisplay.tsx (1)
  • MediaDisplay (29-84)
components/utils/tooltip/UserProfileTooltipWrapper.tsx (1)
  • UserProfileTooltipWrapper (12-34)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx (1)
  • WaveLeaderboardGalleryItemVotes (11-44)
helpers/Helpers.ts (1)
  • formatNumberWithCommas (103-120)
⏰ 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 (1)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (1)

26-27: artFocused default intentionally changed to true

The default for artFocused is now true, making art-focused styling (subtler vote colors, specific hover behavior) the standard for all gallery items. The single production usage in WaveLeaderboardGallery.tsx does not pass artFocused explicitly and will render in this art-focused mode by default. Tests confirm both artFocused={true} and artFocused={false} behaviors are intentional, so no changes to call sites are needed.

Comment thread components/drops/view/utils/DropVoteProgressing.tsx Outdated
Comment thread components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
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

♻️ Duplicate comments (1)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (1)

107-107: Fix the Tailwind prefix on touch-none.

The class touch-none should be tw-touch-none to match the project's Tailwind prefix convention. This was previously identified and remains unaddressed.

Apply this diff:

-    const baseImageClasses = "tw-aspect-square tw-relative tw-cursor-pointer touch-none tw-overflow-hidden tw-bg-iron-900 tw-group/image";
+    const baseImageClasses = "tw-aspect-square tw-relative tw-cursor-pointer tw-touch-none tw-overflow-hidden tw-bg-iron-900 tw-group/image";
🧹 Nitpick comments (1)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (1)

109-111: Consider inverting the condition for clarity.

The negated condition !hasTouchScreen could be rewritten positively for improved readability.

As per SonarCloud hint.

Apply this diff:

-    const imageScaleClasses = !hasTouchScreen
-      ? `tw-transform tw-duration-700 tw-ease-out group-hover/image:tw-scale-105 ${highlightAnimation}`
-      : "";
+    const imageScaleClasses = hasTouchScreen
+      ? ""
+      : `tw-transform tw-duration-700 tw-ease-out group-hover/image:tw-scale-105 ${highlightAnimation}`;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 580376b and 0d63740.

📒 Files selected for processing (1)
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (4 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/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
🧠 Learnings (4)
📚 Learning: 2025-12-03T14:52:34.255Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.255Z
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/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
📚 Learning: 2025-12-03T14:52:34.255Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.255Z
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/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
📚 Learning: 2025-12-05T10:55:30.859Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.859Z
Learning: Applies to **/*.{ts,tsx} : Remove unnecessary Effects; if Effect only derives state, compute during render instead

Applied to files:

  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
📚 Learning: 2025-12-03T14:52:34.255Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.255Z
Learning: Applies to **/*.{ts,tsx} : 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.)

Applied to files:

  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
🧬 Code graph analysis (1)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (6)
hooks/useDeviceInfo.ts (1)
  • useDeviceInfo (23-93)
hooks/drops/useDropInteractionRules.ts (1)
  • useDropInteractionRules (26-140)
components/drops/view/item/content/media/MediaDisplay.tsx (1)
  • MediaDisplay (29-84)
components/utils/tooltip/UserProfileTooltipWrapper.tsx (1)
  • UserProfileTooltipWrapper (12-34)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItemVotes.tsx (1)
  • WaveLeaderboardGalleryItemVotes (11-44)
helpers/Helpers.ts (1)
  • formatNumberWithCommas (103-120)
🪛 GitHub Check: SonarCloud Code Analysis
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx

[warning] 109-109: Unexpected negated condition.

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

⏰ 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 (2)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (2)

34-69: LGTM! Solid animation state management.

The refactoring from useState to useRef for animation tracking is appropriate, and the timer cleanup logic properly prevents memory leaks.


130-201: LGTM! Well-structured content layout.

The refactored rendering structure with title, author, vote stats, and conditional vote button is clear and follows React best practices.

Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Dec 5, 2025

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/voting/VotingModalButton.tsx (2)

5-9: Remove inline comment on variant prop.

TS/TSX files here avoid inline comments; the variant name and union type are self-explanatory, so the // Add variant prop for styling flexibility comment should be removed to match the no-comments guideline.


1-3: Prefer named React type imports and explicit event typing.

To align with the guideline of using named imports for React types and modern JSX runtimes, consider switching to FC/MouseEvent imports and dropping the default React value import, while tightening the event type:

-import React from "react";
+import type { FC, MouseEvent } from "react";
@@
-const VotingModalButton: React.FC<VotingModalButtonProps> = ({
+const VotingModalButton: FC<VotingModalButtonProps> = ({
@@
-  const handleClick = (e: React.MouseEvent) => {
+  const handleClick = (e: MouseEvent<HTMLButtonElement>) => {

This follows the React 19 / Next 16 modernization direction and keeps types explicit. Based on learnings, this moves the component toward the preferred style.

Please confirm this adjustment still passes tsc --noEmit and your ESLint checks in the repo.

Also applies to: 11-25

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad8308b and e2d9283.

📒 Files selected for processing (1)
  • components/voting/VotingModalButton.tsx (1 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/voting/VotingModalButton.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/voting/VotingModalButton.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/voting/VotingModalButton.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/voting/VotingModalButton.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.255Z
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-03T14:52:34.255Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.255Z
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/voting/VotingModalButton.tsx
🔇 Additional comments (2)
components/voting/VotingModalButton.tsx (2)

27-32: Variant class composition looks clear and consistent.

The baseClasses plus variantClasses split keeps shared layout/transition concerns separate from the "default"/"subtle" visual variants and reads cleanly; no issues from a correctness or maintainability standpoint.


37-37: Copy change to “Vote” is fine; just confirm UX/i18n expectations.

The shorter label fits the compact button and is semantically clear; as long as this matches product copy and any localization strategy, it looks good to keep.

Please double-check with design/copy or i18n owners that “Vote” is the intended final string for this control.

@ragnep ragnep merged commit 91d0a29 into main Dec 5, 2025
9 checks passed
@ragnep ragnep deleted the leaderboard-grid-card-redesign branch December 5, 2025 17:54
This was referenced Dec 10, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Dec 19, 2025
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