Conversation
WalkthroughThe PR reorganizes drop components across memes and waves systems with consistent spacing adjustments (3.25rem → 3.5rem margins), introduces voting modals in participation drops, adds mobile/touch support with device detection and long-press handlers, modularizes components into sub-components, adjusts avatar sizing, and updates two public component APIs to accept onDropClick callbacks and wave data. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
|
There was a problem hiding this comment.
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 (5)
components/memes/drops/MemeParticipationDrop.tsx (1)
59-85: Guarddrop.parts[0]access in reply/quote handlers to avoid crashes on empty parts.artworkMediais already usingat(0), buthandleOnReply/handleOnQuotewill throw ifdrop.parts.length === 0.const handleOnReply = useCallback(() => { - onReply({ drop, partId: drop.parts[0].part_id }); + const partId = drop.parts.at(0)?.part_id; + if (!partId) return; + onReply({ drop, partId }); }, [onReply, drop]); const handleOnQuote = useCallback(() => { - onQuote({ drop, partId: drop.parts[0].part_id }); + const partId = drop.parts.at(0)?.part_id; + if (!partId) return; + onQuote({ drop, partId }); }, [onQuote, drop]);components/waves/winners/drops/header/WaveWinnersDropHeaderAuthorPfp.tsx (1)
12-21: Replace<img>withnext/imageto satisfy Next.js ESLint rules.
This component still renders a raw<img>(Line 17-21), which will typically trip@next/next/no-img-element. As per coding guidelines, use<Image />.+import Image from "next/image"; ... - <img - src={winner.drop.author.pfp} - alt="Profile picture" - className="tw-bg-transparent tw-max-w-full tw-max-h-full tw-h-auto tw-w-auto tw-mx-auto tw-object-contain" - /> + <Image + src={winner.drop.author.pfp} + alt="Profile picture" + width={44} + height={44} + className="tw-bg-transparent tw-max-w-full tw-max-h-full tw-h-auto tw-w-auto tw-mx-auto tw-object-contain" + />As per coding guidelines, this should be migrated to
next/image.components/waves/leaderboard/drops/header/WaveLeaderboardDropAuthor.tsx (1)
27-43: Replace<img>withnext/imagein the avatar (ESLint/Core Web Vitals).
<img>is still used fordrop.author.pfp(Line 32-37).+import Image from "next/image"; ... - <img - src={drop.author.pfp} - alt="Profile picture" - className="tw-bg-transparent tw-max-w-full tw-max-h-full tw-h-auto tw-w-auto tw-mx-auto tw-object-contain" - /> + <Image + src={drop.author.pfp} + alt="Profile picture" + width={44} + height={44} + className="tw-bg-transparent tw-max-w-full tw-max-h-full tw-h-auto tw-w-auto tw-mx-auto tw-object-contain" + />As per coding guidelines, internal images should use
next/image.components/waves/drops/ArtistPreviewModalHeader.tsx (1)
46-85: Replace<img>withnext/imageand use FontAwesome for the close icon (project standards compliance).
- Avatar still uses
<img>(lines 49-54); replace with<Image />fromnext/imagewithwidth={44}andheight={44}to match container dimensions.- Close button uses Heroicons; replace
XMarkIconfrom@heroicons/reactwith FontAwesome (project standard per.cursorrules).-import { XMarkIcon } from "@heroicons/react/24/outline"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faXmark } from "@fortawesome/free-solid-svg-icons"; +import Image from "next/image"; ... {user.pfp && ( - <img - src={user.pfp} - alt="Profile" - className="tw-w-full tw-h-full tw-object-contain tw-bg-transparent" - /> + <Image + src={user.pfp} + alt="Profile" + width={44} + height={44} + className="tw-w-full tw-h-full tw-object-contain tw-bg-transparent" + /> )} ... - <XMarkIcon className="tw-w-5 tw-h-5 tw-flex-shrink-0" /> + <FontAwesomeIcon icon={faXmark} className="tw-w-5 tw-h-5 tw-flex-shrink-0" />components/waves/drops/WaveDrop.tsx (1)
394-400: Make the width calc consistent with the new 3.5rem left offset.
tw-w-[calc(100%-3.25rem)]+tw-ml-[3.5rem]is internally inconsistent and can cause layout issues.- className={`tw-mx-2 tw-flex tw-w-[calc(100%-3.25rem)] tw-ml-[3.5rem] tw-items-center tw-gap-x-2 tw-gap-y-1 tw-flex-wrap`}> + className={`tw-mx-2 tw-flex tw-w-[calc(100%-3.5rem)] tw-ml-[3.5rem] tw-items-center tw-gap-x-2 tw-gap-y-1 tw-flex-wrap`}>
🧹 Nitpick comments (3)
components/waves/drops/winner/DefaultWinnerDrop.tsx (1)
3-10: Prefer direct React type imports overReact.RefObjectfor TS consistency.
Guidelines prefer named imports/types; you can avoid theReact.namespace inparentContainerRef.-import { memo, useCallback, useState } from "react"; +import { memo, useCallback, useState } from "react"; +import type { RefObject } from "react"; ... - readonly parentContainerRef?: React.RefObject<HTMLElement | null>; + readonly parentContainerRef?: RefObject<HTMLElement | null>;As per coding guidelines, prefer named imports for React hooks and types.
Also applies to: 86-87
components/waves/drops/participation/ParticipationDropMetadata.tsx (1)
4-7: Guard against non-unique/nullablemeta.data_keyfor Tooltip IDs + React keys.
Ifmeta.data_keyisn’t guaranteed unique/present,buildTooltipId(...)(Line 21) andkey={meta.data_key}can collide.- const tooltipId = buildTooltipId("metadata", contextId, meta.data_key); + const metaKey = meta.data_key ?? "unknown-key"; + const tooltipId = buildTooltipId("metadata", contextId, metaKey);And in the maps:
- key={meta.data_key} + key={`${contextId ?? "ctx"}:${meta.data_key ?? meta.data_value}`}Given
react-tooltipbehavior can vary by version, please sanity-check in-app (hover, focus, portal layering).Also applies to: 21-47
components/waves/drops/WaveDropAuthorPfp.tsx (1)
23-31: Good sizing alignment; consider droppingReact.namespace types/imports.
The 44pxsizesmatches the newtw-h-11 tw-w-11container well, but this file still relies onReact.FC/React.MouseEvent. Consider switching to named imports (FC,MouseEvent) to match repo guidelines.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
components/memes/drops/MemeParticipationDrop.tsx(2 hunks)components/waves/drops/ArtistPreviewModalHeader.tsx(1 hunks)components/waves/drops/WaveDrop.tsx(4 hunks)components/waves/drops/WaveDropAuthorPfp.tsx(1 hunks)components/waves/drops/participation/ParticipationDropFooter.tsx(3 hunks)components/waves/drops/participation/ParticipationDropHeader.tsx(1 hunks)components/waves/drops/participation/ParticipationDropMetadata.tsx(2 hunks)components/waves/drops/winner/DefaultWinnerDrop.tsx(2 hunks)components/waves/leaderboard/drops/DefaultWaveLeaderboardDrop.tsx(3 hunks)components/waves/leaderboard/drops/header/WaveLeaderboardDropAuthor.tsx(3 hunks)components/waves/winners/drops/DefaultWaveWinnerDrop.tsx(2 hunks)components/waves/winners/drops/header/WaveWinnersDropHeaderAuthorPfp.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 />fromnext/imageto satisfy@next/next/no-img-elementESLint rule
Use<Link href="/path">from Next.js for internal navigation instead of plain HTML links to satisfy@next/next/no-html-link-for-pagesESLint rule
Files:
components/waves/drops/WaveDropAuthorPfp.tsxcomponents/waves/drops/ArtistPreviewModalHeader.tsxcomponents/waves/winners/drops/DefaultWaveWinnerDrop.tsxcomponents/waves/drops/participation/ParticipationDropHeader.tsxcomponents/waves/winners/drops/header/WaveWinnersDropHeaderAuthorPfp.tsxcomponents/waves/leaderboard/drops/DefaultWaveLeaderboardDrop.tsxcomponents/waves/drops/participation/ParticipationDropMetadata.tsxcomponents/waves/drops/winner/DefaultWinnerDrop.tsxcomponents/waves/drops/WaveDrop.tsxcomponents/waves/drops/participation/ParticipationDropFooter.tsxcomponents/memes/drops/MemeParticipationDrop.tsxcomponents/waves/leaderboard/drops/header/WaveLeaderboardDropAuthor.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 addreadonlybefore props in React components
Files:
components/waves/drops/WaveDropAuthorPfp.tsxcomponents/waves/drops/ArtistPreviewModalHeader.tsxcomponents/waves/winners/drops/DefaultWaveWinnerDrop.tsxcomponents/waves/drops/participation/ParticipationDropHeader.tsxcomponents/waves/winners/drops/header/WaveWinnersDropHeaderAuthorPfp.tsxcomponents/waves/leaderboard/drops/DefaultWaveLeaderboardDrop.tsxcomponents/waves/drops/participation/ParticipationDropMetadata.tsxcomponents/waves/drops/winner/DefaultWinnerDrop.tsxcomponents/waves/drops/WaveDrop.tsxcomponents/waves/drops/participation/ParticipationDropFooter.tsxcomponents/memes/drops/MemeParticipationDrop.tsxcomponents/waves/leaderboard/drops/header/WaveLeaderboardDropAuthor.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 usenext/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/drops/WaveDropAuthorPfp.tsxcomponents/waves/drops/ArtistPreviewModalHeader.tsxcomponents/waves/winners/drops/DefaultWaveWinnerDrop.tsxcomponents/waves/drops/participation/ParticipationDropHeader.tsxcomponents/waves/winners/drops/header/WaveWinnersDropHeaderAuthorPfp.tsxcomponents/waves/leaderboard/drops/DefaultWaveLeaderboardDrop.tsxcomponents/waves/drops/participation/ParticipationDropMetadata.tsxcomponents/waves/drops/winner/DefaultWinnerDrop.tsxcomponents/waves/drops/WaveDrop.tsxcomponents/waves/drops/participation/ParticipationDropFooter.tsxcomponents/memes/drops/MemeParticipationDrop.tsxcomponents/waves/leaderboard/drops/header/WaveLeaderboardDropAuthor.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Must passtsc --noEmittype checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage (React.useMemo,React.useRef, etc.)
If thereact-hooks/exhaustive-depslint 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 inuseEffectEvent
**/*.{ts,tsx}: Must passtsc --noEmitfor 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
UseuseEffectEventfor non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs:<Link>for internal links,next/imagefor 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 />fromnext/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/drops/WaveDropAuthorPfp.tsxcomponents/waves/drops/ArtistPreviewModalHeader.tsxcomponents/waves/winners/drops/DefaultWaveWinnerDrop.tsxcomponents/waves/drops/participation/ParticipationDropHeader.tsxcomponents/waves/winners/drops/header/WaveWinnersDropHeaderAuthorPfp.tsxcomponents/waves/leaderboard/drops/DefaultWaveLeaderboardDrop.tsxcomponents/waves/drops/participation/ParticipationDropMetadata.tsxcomponents/waves/drops/winner/DefaultWinnerDrop.tsxcomponents/waves/drops/WaveDrop.tsxcomponents/waves/drops/participation/ParticipationDropFooter.tsxcomponents/memes/drops/MemeParticipationDrop.tsxcomponents/waves/leaderboard/drops/header/WaveLeaderboardDropAuthor.tsx
🧠 Learnings (4)
📚 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 **/*.{ts,tsx,js,jsx} : Include all required imports and ensure proper naming of key components
Applied to files:
components/waves/winners/drops/DefaultWaveWinnerDrop.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:
components/waves/winners/drops/DefaultWaveWinnerDrop.tsxcomponents/waves/leaderboard/drops/DefaultWaveLeaderboardDrop.tsxcomponents/waves/drops/winner/DefaultWinnerDrop.tsxcomponents/waves/drops/WaveDrop.tsxcomponents/memes/drops/MemeParticipationDrop.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/waves/winners/drops/DefaultWaveWinnerDrop.tsxcomponents/waves/drops/winner/DefaultWinnerDrop.tsxcomponents/waves/drops/WaveDrop.tsxcomponents/waves/drops/participation/ParticipationDropFooter.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/waves/drops/winner/DefaultWinnerDrop.tsxcomponents/waves/drops/WaveDrop.tsxcomponents/memes/drops/MemeParticipationDrop.tsx
🧬 Code graph analysis (1)
components/waves/drops/participation/ParticipationDropHeader.tsx (1)
components/user/utils/UserCICAndLevel.tsx (1)
UserCICAndLevel(11-53)
⏰ 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/memes/drops/MemeParticipationDrop.tsx (2)
3-19: Imports + modular subcomponents integration looks coherent.
104-110: Alignment tweak (sm:tw-ml-[3.75rem] → sm:tw-ml-[3.5rem]) is straightforward and localized.components/waves/leaderboard/drops/header/WaveLeaderboardDropAuthor.tsx (1)
45-73: New author vertical stack + dedicated badge row looks consistent.
The split into two rows (Line 45-73) reads cleaner and should improve alignment predictability.components/waves/drops/winner/DefaultWinnerDrop.tsx (1)
234-242: Spacing tweak totw-ml-[3.5rem]matches the PR’s alignment goal.
Looks consistent with the other 3.5rem left-alignment shifts.components/waves/drops/participation/ParticipationDropMetadata.tsx (1)
72-73: Margin shift tosm:tw-ml-[3.5rem]aligns with the PR’s layout changes.components/waves/drops/participation/ParticipationDropHeader.tsx (1)
24-53: Header layout split (author/time + badge row) looks cleaner and should help alignment.
Only potential footgun: the Link useshref={\/${drop.author.handle}`}(Line 35-36). Ifhandle` can be null/empty, consider guarding or falling back to a safe route/id.components/waves/drops/participation/ParticipationDropFooter.tsx (1)
3-57: Modal voting wiring looks reasonable; please smoke-test event propagation + a11y behaviors.
Specifically: clicking inside the modal should not trigger any parent “drop” click handlers, and desktop should support Escape/focus trap as expected (depends onMobileVotingModal/VotingModalimplementation).components/waves/leaderboard/drops/DefaultWaveLeaderboardDrop.tsx (1)
63-67: Verify long-press doesn’t also triggeronDropClick.
Same pattern:onClickon the outer wrapper +touchHandlerson the inner wrapper; please confirm long-press opens the mobile menu without also navigating/opening the drop.Also applies to: 122-145
components/waves/winners/drops/DefaultWaveWinnerDrop.tsx (1)
68-72: AddstopPropagation()to the outeronClickhandler orpreventDefault()ontouchEndto prevent synthetic clicks.Long-press handlers are on the inner div, but
onClickis on the outer div. On iOS/Android, releasing a long-press can synthesize a click event that bubbles to the outer div, causing both the menu to open and theonDropClickaction to fire. Wrap theonClickhandler withstopPropagation()or prevent synthetic clicks in theuseLongPressInteractionhook'shandleTouchEnd.This applies to lines 68–72, 72–90 (inner content), and 130–146 (menu portal).
| <div className="tw-mt-4 tw-px-4 tw-flex tw-w-[calc(100%-3.25rem)] tw-ml-[3.5rem] tw-items-center tw-gap-x-2 tw-gap-y-1 tw-flex-wrap"> | ||
| <WaveDropReactions drop={drop} /> | ||
| </div> |
There was a problem hiding this comment.
Fix width calc mismatch: calc(100% - 3.25rem) should match tw-ml-[3.5rem].
Right now the row is offset by 3.5rem but only shrinks by 3.25rem, which can cause subtle overflow/misalignment.
- <div className="tw-mt-4 tw-px-4 tw-flex tw-w-[calc(100%-3.25rem)] tw-ml-[3.5rem] tw-items-center tw-gap-x-2 tw-gap-y-1 tw-flex-wrap">
+ <div className="tw-mt-4 tw-px-4 tw-flex tw-w-[calc(100%-3.5rem)] tw-ml-[3.5rem] tw-items-center tw-gap-x-2 tw-gap-y-1 tw-flex-wrap">
<WaveDropReactions drop={drop} />
</div>🤖 Prompt for AI Agents
In components/waves/drops/participation/ParticipationDropFooter.tsx around lines
68 to 70, the container uses tw-w-[calc(100%-3.25rem)] while the left margin is
tw-ml-[3.5rem], causing a 0.25rem mismatch and potential overflow; change the
calc to tw-w-[calc(100%-3.5rem)] (or otherwise ensure both values come from the
same constant/utility) so the width subtraction matches the left margin exactly.
| import { ApiDrop } from "@/generated/models/ApiDrop"; | ||
| import { ApiDropMentionedUser } from "@/generated/models/ApiDropMentionedUser"; | ||
| import { ApiDropType } from "@/generated/models/ApiDropType"; | ||
| import { ApiUpdateDropRequest } from "@/generated/models/ApiUpdateDropRequest"; | ||
| import { ExtendedDrop } from "@/helpers/waves/drop.helpers"; | ||
| import { useDropUpdateMutation } from "@/hooks/drops/useDropUpdateMutation"; | ||
| import useIsMobileDevice from "@/hooks/isMobileDevice"; | ||
| import { selectEditingDropId, setEditingDropId } from "@/store/editSlice"; | ||
| import { ActiveDropState } from "@/types/dropInteractionTypes"; | ||
| import { memo, useCallback, useEffect, useRef, useState } from "react"; | ||
| import { useDispatch, useSelector } from "react-redux"; | ||
| import { DropInteractionParams, DropLocation } from "./Drop"; |
There was a problem hiding this comment.
Fix TypeScript: React.* types used without importing React.
After switching to named imports from "react", the file still references React.RefObject / React.TouchEvent, which will fail tsc --noEmit.
- import { memo, useCallback, useEffect, useRef, useState } from "react";
+ import {
+ memo,
+ useCallback,
+ useEffect,
+ useRef,
+ useState,
+ type RefObject,
+ type TouchEvent,
+ } from "react";
interface WaveDropProps {
readonly drop: ExtendedDrop;
...
- readonly parentContainerRef?: React.RefObject<HTMLElement | null>;
+ readonly parentContainerRef?: RefObject<HTMLElement | null>;
}
const handleTouchStart = useCallback(
- (e: React.TouchEvent) => {
+ (e: TouchEvent) => {
...
},
...
);
- const handleTouchEnd = useCallback((e: React.TouchEvent) => {
+ const handleTouchEnd = useCallback((e: TouchEvent) => {
...
}, []);
- const handleTouchMove = useCallback((e: React.TouchEvent) => {
+ const handleTouchMove = useCallback((e: TouchEvent) => {
...
}, []);Also applies to: 117-132, 193-213
🤖 Prompt for AI Agents
In components/waves/drops/WaveDrop.tsx around lines 3-14 (and also where
React.RefObject / React.TouchEvent are used at 117-132 and 193-213), the code
references React types but only uses named imports from "react"; add the missing
type imports (e.g., RefObject and TouchEvent — or any other React.* types used)
to the existing import from 'react' so the file imports these types directly (or
alternatively import React as a namespace), then update any type annotations if
necessary to use the newly imported names.
| import CommonDropdownItemsMobileWrapper from "@/components/utils/select/dropdown/CommonDropdownItemsMobileWrapper"; | ||
| import { MobileVotingModal, VotingModal } from "@/components/voting"; | ||
| import VotingModalButton from "@/components/voting/VotingModalButton"; | ||
| import WaveDropActionsOpen from "@/components/waves/drops/WaveDropActionsOpen"; | ||
| import WaveDropMobileMenuOpen from "@/components/waves/drops/WaveDropMobileMenuOpen"; | ||
| import WaveDropActionsOptions from "@/components/waves/drops/WaveDropActionsOptions"; | ||
| import WaveDropMobileMenuDelete from "@/components/waves/drops/WaveDropMobileMenuDelete"; | ||
| import { VotingModal, MobileVotingModal } from "@/components/voting"; | ||
| import VotingModalButton from "@/components/voting/VotingModalButton"; | ||
| import WaveDropMobileMenuOpen from "@/components/waves/drops/WaveDropMobileMenuOpen"; | ||
| import { ApiWave } from "@/generated/models/ObjectSerializer"; | ||
| import { ExtendedDrop } from "@/helpers/waves/drop.helpers"; | ||
| import { useDropInteractionRules } from "@/hooks/drops/useDropInteractionRules"; | ||
| import useIsMobileScreen from "@/hooks/isMobileScreen"; | ||
| import useDeviceInfo from "@/hooks/useDeviceInfo"; | ||
| import CommonDropdownItemsMobileWrapper from "@/components/utils/select/dropdown/CommonDropdownItemsMobileWrapper"; | ||
| import useLongPressInteraction from "@/hooks/useLongPressInteraction"; | ||
| import React, { useState } from "react"; | ||
| import { createPortal } from "react-dom"; | ||
| import { WaveLeaderboardDropContent } from "../content/WaveLeaderboardDropContent"; | ||
| import { WaveLeaderboardDropFooter } from "./footer/WaveLeaderboardDropFooter"; | ||
| import { WaveLeaderboardDropHeader } from "./header/WaveLeaderboardDropHeader"; | ||
| import { WaveLeaderboardDropRaters } from "./header/WaveleaderboardDropRaters"; | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for the actual file with its correct casing
echo "=== Searching for the actual file ==="
fd -a "Wave.*DropRaters\.(ts|tsx)$" . | head -20
echo ""
echo "=== Checking all import statements with case-insensitive search ==="
rg -in "waveleaderboarddropraters|wavelearboard" . --type=ts --type=tsx | head -30
echo ""
echo "=== Checking specific import statements in the target file ==="
rg -n "WaveleaderboardDropRaters|WaveLeaderboardDropRaters" . --type=ts --type=tsxRepository: 6529-Collections/6529seize-frontend
Length of output: 413
🏁 Script executed:
#!/bin/bash
# Read the specific import line from the target file to verify the exact casing
echo "=== Reading import lines from DefaultWaveLeaderboardDrop.tsx ==="
sed -n '1,30p' components/waves/leaderboard/drops/DefaultWaveLeaderboardDrop.tsx | grep -i "waveleaderboard\|waveleaderboard"
echo ""
echo "=== Listing the actual header file to confirm casing ==="
ls -la components/waves/leaderboard/drops/header/ | grep -i ratersRepository: 6529-Collections/6529seize-frontend
Length of output: 733
🏁 Script executed:
#!/bin/bash
# Check the actual export from the WaveleaderboardDropRaters.tsx file
echo "=== Reading WaveleaderboardDropRaters.tsx export ==="
head -50 components/waves/leaderboard/drops/header/WaveleaderboardDropRaters.tsx | grep -E "export|const|function"
echo ""
echo "=== Check full export statement ==="
rg "export.*WaveLeaderboard|export.*Waveleaderboard" components/waves/leaderboard/drops/header/WaveleaderboardDropRaters.tsx -A 2Repository: 6529-Collections/6529seize-frontend
Length of output: 643
Fix import path casing: file should be named WaveLeaderboardDropRaters.tsx.
The component exports WaveLeaderboardDropRaters but the file is named WaveleaderboardDropRaters.tsx (with lowercase 'leaderboard'). This mismatch will break on case-sensitive filesystems (Linux/macOS CI). Rename the file to match the exported component name.
🤖 Prompt for AI Agents
In components/waves/leaderboard/drops/DefaultWaveLeaderboardDrop.tsx around
lines 3 to 22, the import path for WaveLeaderboardDropRaters uses a filename
with a lowercase "leaderboard" that doesn't match the exported component name;
rename the physical file from WaveleaderboardDropRaters.tsx to
WaveLeaderboardDropRaters.tsx and update the import in this file to import {
WaveLeaderboardDropRaters } from "./header/WaveLeaderboardDropRaters"; ensure
git tracks the rename (use git mv) so case-only change is reflected on
case-insensitive systems and run the build to verify no other imports reference
the old casing.
| import CommonDropdownItemsMobileWrapper from "@/components/utils/select/dropdown/CommonDropdownItemsMobileWrapper"; | ||
| import WaveDropActionsOpen from "@/components/waves/drops/WaveDropActionsOpen"; | ||
| import WaveDropMobileMenuOpen from "@/components/waves/drops/WaveDropMobileMenuOpen"; | ||
| import { ApiWaveDecisionWinner } from "@/generated/models/ApiWaveDecisionWinner"; | ||
| import { formatNumberWithCommas } from "@/helpers/Helpers"; | ||
| import { | ||
| ExtendedDrop, | ||
| convertApiDropToExtendedDrop, | ||
| ExtendedDrop, | ||
| convertApiDropToExtendedDrop, | ||
| } from "@/helpers/waves/drop.helpers"; | ||
| import useDeviceInfo from "@/hooks/useDeviceInfo"; | ||
| import useLongPressInteraction from "@/hooks/useLongPressInteraction"; | ||
| import React from "react"; | ||
| import { createPortal } from "react-dom"; | ||
| import { WaveWinnersDropHeader } from "./header/WaveWinnersDropHeader"; | ||
| import { WaveWinnersDropContent } from "./WaveWinnersDropContent"; | ||
| import WaveWinnersDropOutcome from "./header/WaveWinnersDropOutcome"; | ||
| import { ApiWaveDecisionWinner } from "@/generated/models/ApiWaveDecisionWinner"; | ||
| import WaveWinnersDropHeaderAuthorPfp from "./header/WaveWinnersDropHeaderAuthorPfp"; | ||
| import WaveWinnersDropHeaderTotalVotes from "./header/WaveWinnersDropHeaderTotalVotes"; | ||
| import WaveWinnersDropHeaderVoters from "./header/WaveWinnersDropHeaderVoters"; | ||
| import useDeviceInfo from "@/hooks/useDeviceInfo"; | ||
| import useLongPressInteraction from "@/hooks/useLongPressInteraction"; | ||
| import WaveDropActionsOpen from "@/components/waves/drops/WaveDropActionsOpen"; | ||
| import CommonDropdownItemsMobileWrapper from "@/components/utils/select/dropdown/CommonDropdownItemsMobileWrapper"; | ||
| import WaveDropMobileMenuOpen from "@/components/waves/drops/WaveDropMobileMenuOpen"; | ||
| import { formatNumberWithCommas } from "@/helpers/Helpers"; | ||
| import WaveWinnersDropOutcome from "./header/WaveWinnersDropOutcome"; | ||
| import { WaveWinnersDropContent } from "./WaveWinnersDropContent"; | ||
|
|
There was a problem hiding this comment.
Add "use client"; (module uses document + client hooks).
This file uses createPortal(... document.body) and client hooks; it should be a Client Component.
+ "use client";
+
import CommonDropdownItemsMobileWrapper from "@/components/utils/select/dropdown/CommonDropdownItemsMobileWrapper";
...Also applies to: 130-146
🤖 Prompt for AI Agents
components/waves/winners/drops/DefaultWaveWinnerDrop.tsx lines 1-20 (also
applies to lines 130-146): this module uses document (createPortal) and
client-only hooks, so it must be a Next.js Client Component; add the directive
"use client"; as the very first line of the file (above all imports) to mark the
file as a client component and prevent server-side rendering errors.



Summary by CodeRabbit
New Features
Style
✏️ Tip: You can customize this high-level summary in your review settings.