Skip to content

Fix no unused parameters#1695

Merged
simo6529 merged 3 commits intomainfrom
fix-noUnusedParameters
Jan 3, 2026
Merged

Fix no unused parameters#1695
simo6529 merged 3 commits intomainfrom
fix-noUnusedParameters

Conversation

@simo6529
Copy link
Copy Markdown
Collaborator

@simo6529 simo6529 commented Jan 3, 2026

Summary by CodeRabbit

  • Refactor

    • Simplified component interfaces by removing unused properties and streamlined internal type definitions.
    • Modernized codebase to use automatic JSX runtime, removing explicit React imports across multiple components.
  • Improvements

    • Increased file upload size limit to 200MB.
    • Adjusted numeric display precision to use default formatting for gas and royalty values.

✏️ 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>
Signed-off-by: Simo <simo@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 3, 2026

📝 Walkthrough

Walkthrough

Large-scale refactoring removing unused React imports across components, eliminating unused prop parameters from component signatures (profile, parentContainerRef, setToasts, thresholdTimeMs, etc.), cleaning up unused type definitions from entity files, and simplifying function signatures and formatting consistency.

Changes

Cohort / File(s) Summary
React Import Removals
components/auth/error-boundary/WalletErrorBoundary.tsx, components/brain/notifications/NotificationsWrapper.tsx, components/common/icons/*, components/drops/create/lexical/plugins/mentions/MentionsPlugin.tsx, components/drops/view/item/content/media/DropListItemContentMediaGLB.tsx, components/groups/page/create/config/*, components/header/user/HeaderUserConnect.tsx, components/home/*, components/layout/*, components/layout/sidebar/WebSidebarUser.tsx, components/memes/drops/*, components/navigation/NavItem.tsx, components/nextGen/collections/collectionParts/NextGenCollectionSlideshow.tsx, components/notifications/NotificationsPage.tsx, components/utils/Spinner.tsx, components/utils/icons/*, components/waves/*
Removed explicit import React from 'react' across 50+ files, relying on automatic JSX runtime; all functionality preserved.
Distribution Plan Tool Context Cleanup
components/distribution-plan-tool/create-snapshots/form/CreateSnapshotFormSearchCollectionDropdownItem.tsx, components/distribution-plan-tool/create-snapshots/table/CreateSnapshotTableRowDownload.tsx, components/distribution-plan-tool/map-delegations/MapDelegationsForm.tsx, components/distribution-plan-tool/review-distribution-plan/table/ReviewDistributionPlanTableHeader.tsx
Removed setToasts consumption from DistributionPlanToolContext; components now only use distributionPlan and related values.
Drop Component Prop Removals
components/drops/create/DropEditor.tsx, components/drops/create/compact/CreateDropCompact.tsx, components/drops/create/full/CreateDropFull.tsx, components/drops/create/full/desktop/CreateDropFullDesktop.tsx, components/drops/create/full/mobile/CreateDropFullMobile.tsx, components/drops/create/utils/CreateDropWrapper.tsx
Removed public props: profile: ProfileMinWithoutSubs, showProfile, setMentionedUsers, title, metadata, onMetadataRemove from drop creation component interfaces.
Wave Drop parentContainerRef Removal
components/waves/drops/Drop.tsx, components/waves/drops/WaveDrop.tsx, components/waves/drops/WaveDropContent.tsx, components/waves/drops/participation/EndedParticipationDrop.tsx, components/waves/drops/participation/OngoingParticipationDrop.tsx, components/waves/drops/participation/ParticipationDropContent.tsx, components/waves/drops/winner/DefaultWinnerDrop.tsx
Removed parentContainerRef?: React.RefObject<HTMLElement | null> prop from wave/participation/winner drop component signatures.
Wave Approval Threshold Removal
components/waves/create-wave/CreateWave.tsx, components/waves/create-wave/approval/CreateWaveApproval.tsx, components/waves/create-wave/approval/CreateWaveApprovalThresholdTime.tsx
Removed thresholdTimeMs prop from wave approval threshold components' public interfaces.
Wave Rolling Mode Handler Removal
components/waves/create-wave/dates/CreateWaveDates.tsx, components/waves/create-wave/dates/RollingEndDate.tsx
Removed setIsRollingMode callback prop from rolling date components; eliminated handleRollingInteraction local handler.
Wave Outcomes CIC Prop Removal
components/waves/create-wave/outcomes/winners/rows/CreateWaveOutcomesRow.tsx, components/waves/create-wave/outcomes/winners/rows/cic/CreateWaveOutcomesRowCIC.tsx, components/waves/create-wave/outcomes/winners/rows/cic/CreateWaveOutcomesRowCICApprove.tsx, components/waves/create-wave/outcomes/winners/rows/cic/CreateWaveOutcomesRowCICRank.tsx
Removed removeOutcome: () => void prop from CIC outcome row components.
Dropdown Position Logic Removal
components/utils/select/dropdown/CommonDropdown.tsx, components/utils/select/dropdown/CommonDropdownItemsDefaultWrapper.tsx, components/utils/select/dropdown/CommonDropdownItemsWrapper.tsx, components/user/xtdh/user-page-xtdh-granted-list/components/UserPageXtdhGrantedStatusDropdown.tsx
Removed containerRef, buttonPosition props and dynamic positioning logic; eliminated getButtonPosition helper and position state management.
Profile Activity Filter Prop Removal
components/profile-activity/filter/ProfileActivityLogsFilter.tsx, components/profile-activity/filter/ProfileActivityLogsFilterList.tsx, components/profile-activity/filter/ProfileActivityLogsFilterListItem.tsx
Removed user: string | null prop from activity log filter components.
User Stats Prop Removals
components/user/stats/UserPageStatsClient.tsx, components/user/stats/tags/UserPageStatsTags.tsx
Removed seasons prop from UserPageStatsTags; reformatted state initializations in UserPageStatsClient.
User Stats Xtdh Changes
components/user/xtdh/UserPageXtdhGrantedList.tsx
Removed activeSortDirection prop and isFetching from hook return; refactored header/subfilters layout structure.
Wave Drop Header Prop Removal
components/waves/header/name/WaveHeaderNameEditInput.tsx, components/waves/header/name/WaveHeaderNameEditModal.tsx
Removed wave: ApiWave prop from WaveHeaderNameEditInput component.
Winner/Badge Prop Removals
components/waves/drops/winner/WinnerDropBadge.tsx, components/waves/drops/ProfileWinnerBadge.tsx
Removed round and title props from winner badge component signatures.
Wave Groups isEligible Removal
components/waves/specs/groups/group/WaveGroup.tsx, components/waves/groups/WaveGroups.tsx
Removed isEligible: boolean prop from WaveGroup component and corresponding usage in WaveGroups.
Layout & Height Calculation Refactor
components/brain/my-stream/layout/LayoutContext.tsx
Removed View union type parameter from calculateHeightStyle(); updated all callers to pass only spaces and capacitorSpace; adjusted mobile/homepage style calculations.
Image Node DOM Import Signature
components/drops/create/lexical/nodes/ImageNode.tsx
Changed img converter from (node: Node) => {...} to () => {...} in static importDOM mapping.
Consolidated Addresses Prop Removal
components/user/identity/statements/consolidated-addresses/UserPageIdentityStatementsConsolidatedAddressesItem.tsx, components/user/identity/statements/consolidated-addresses/UserPageIdentityStatementsConsolidatedAddressesItemPrimary.tsx
Removed address prop from consolidated address primary statement components.
Token Confirmation Modal Signature
components/distribution-plan-tool/review-distribution-plan/table/ReviewDistributionPlanTableSubscriptionFooter.tsx, components/distribution-plan-tool/review-distribution-plan/table/ReviewDistributionPlanTableSubscriptionFooterConfirmTokenId.tsx
Changed handleConfirmTokenId(contract: string, tokenId: string) to handleConfirmTokenId(tokenId: string) and corresponding onConfirm callback signature.
DownloadUrlWidget Cleanup
components/downloadUrlWidget/DownloadUrlWidget.tsx
Removed unused Button/Modal react-bootstrap imports; deleted entire DownloadUrlWidgetConfirm component.
LightDrop Prop Removal
components/waves/drops/LightDrop.tsx
Changed component signature from ({ drop }) to (), making component non-reliant on props while preserving JSX.
Event Handler Parameter Removals
components/utils/select-group/SelectGroupModal.tsx, components/utils/select/dropdown/CommonDropdownItemsWrapper.tsx, components/nextGen/collections/nextgenToken/NextGenZoomableImage.tsx, components/waves/drops/WaveDrop.tsx, components/waves/memes/traits/DropdownTrait.tsx, components/waves/memes/traits/NumberTrait.tsx
Removed event parameters from callbacks (e.g., handleDragEnd(e)handleDragEnd()); event handlers simplified to parameter-less functions.
Map Callback Index Removal
components/nextGen/collections/NextGenArtists.tsx, components/user/stats/activity/tdh-history/UserPageStatsActivityTDHHistoryCharts.tsx, components/waves/winners/WaveWinnersSmall.tsx
Removed unused index parameter from map callbacks; refactored as (item, idx)(item).
Copy Clipboard State Cleanup
components/distribution-plan-tool/create-snapshots/table/CreateSnapshotTableRow.tsx
Changed [copyState, copyToClipboard] to [_, copyToClipboard], removing unused state variable.
State Variable Removals
components/memelab/MemeLabCollection.tsx, components/rememes/RememeAddPage.tsx, components/rememes/Rememes.tsx, components/user/proxy/UserPageProxy.tsx
Removed nftBalances state, memesLoaded state, internal ProxyAction enum from various components.
Decimal Precision Changes
components/gas-royalties/Gas.tsx, components/gas-royalties/Royalties.tsx, components/latest-activity/LatestActivityRow.tsx
Removed explicit decimal precision arguments from displayDecimal() calls; now rely on helper defaults instead of explicit 2 or 5 decimal places.
Utility Type Removals
components/leaderboard/leaderboard_helpers.ts, components/waves/create-wave/services/waveDecisionService.ts
Removed LeaderboardSortType type alias; removed generateDecisionPointText and msToTimePeriod internal helper functions.
NFC Details Destructuring Simplification
components/drops/view/item/content/nft-tag/DropListItemContentNftDetails.tsx
Simplified referencedNft destructuring from { contract, token, name: tokenName } to { name: tokenName }; removed commented JSX sections.
Rate Mutation Callback Change
components/drops/view/item/rate/give/DropListItemRateGiveSubmit.tsx
Changed mutation onSuccess from (response: ApiDrop) => {...} to () => {...}, removing unused response parameter.
NextGen Props Changes
components/nextGen/collections/collectionParts/NextGenCollectionDetails.tsx, components/nextGen/collections/collectionParts/NextGenCollectionProvenance.tsx
Removed props from NextGenCollectionDetailsAbout; added optional odd?: boolean prop to NextGenCollectionProvenanceRow.
HeaderUserConnect Signature
components/header/user/HeaderUserConnect.tsx
Changed from (props: Readonly<{}>) to (), removing empty props parameter.
Meme Constants Refactor
components/the-memes/TheMemes.tsx
Removed API_SORT_TO_MEMES constant mapping; updated map callbacks to ignore keys via [_, value].
Meme File Upload Constants
components/waves/memes/file-upload/utils/constants.ts
Removed ACCEPTED_FORMATS export; increased FILE_SIZE_LIMIT from 100MB to 200MB; updated quote style consistency.
Trait Component Handlers
components/waves/memes/traits/TraitField.tsx
Removed exhaustiveness check assignment in TraitFieldComponent; simplified control flow without type safety assertion.
String Formatting Updates
components/waves/memes/submission/steps/AgreementStepAgreement.tsx, components/waves/voting/components/TimeUnitSelector.tsx
Updated quote consistency (single to double quotes); reformatted function parameters to multi-line destructuring.
Type Definition Removals
entities/IDBResponse.ts, entities/IDelegation.ts, entities/IDrop.ts, entities/IProfile.ts, entities/IProxy.ts, entities/IReservoir.ts, entities/ITDH.ts
Removed unused/obsolete interfaces: LeaderboardDBResponse, NewDelegationParams, various DropActivity/Rating types, WalletDelegation, ProfileAvailableDropRateResponse, CreateNewProfileProxy, ReservoirCollection\*, BaseTDHMetrics.
Wave Messages Utils Refactor
contexts/wave/utils/wave-messages-utils.ts
Removed resolveReplacement() helper function; simplified mergeDrops() to directly assign incoming drops without resolution.
DropContext Provider Removal
components/waves/drops/DropContext.tsx
Removed DropProvider component and memoization logic; only context creation and hook remain.
Modal Props Consolidation
components/memes/drops/meme-participation-drop/MemeDropArtistInfo.tsx
Added onClose, user, initialTab props to ArtistPreviewModal invocation.
Formatting & Line Breaks
Multiple files across components
Applied consistent multi-line parameter destructuring, JSX tag reformatting, import consolidation, and newline consistency without functional changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • #1655 — Modifies components/brain/my-stream/layout/LayoutContext.tsx height-calculation logic including calculateHeightStyle viewport handling that overlaps with main PR changes.
  • #1649 — Updates CommonDropdown component usage and CSS classes; main PR removes buttonPosition and positioning logic from the same dropdown components.
  • #1640 — Modifies ProfileWinnerBadge props, ArtistPreviewModal modal wiring with initialTab/onClose/user, and MemeDropArtistInfo integration; overlaps with main PR's artist preview modal changes.

Suggested reviewers

  • ragnep

Poem

🐰 A rabbit's refrain on this grand clean-up day,
Props shed like carrots, old code swept away,
React imports vanish, the runtime flows free,
Simpler signatures bloom like clover, you see,
Types consolidated, handlers made light,
A codebase transformed—now everything's right! 🥬✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.94% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix no unused parameters' accurately reflects the primary change: removing unused function parameters throughout the codebase.
✨ Finishing touches
  • 📝 Generate docstrings

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.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Jan 3, 2026

Quality Gate Failed Quality Gate failed

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

See analysis details on SonarQube Cloud

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 (13)
components/memelab/MemeLabCollection.tsx (1)

167-177: Add key prop to mapped fragments.

Each element in the mapped array should have a unique key to avoid React warnings and ensure proper reconciliation.

🔎 Proposed fix
-                    {website.split(" ").map((w) => (
-                      <>
+                    {website.split(" ").map((w, index) => (
+                      <span key={index}>
                         <a
                           href={addProtocol(w)}
                           target="_blank"
                           rel="noopener noreferrer"
                         >
                           {w}
                         </a>
                         &nbsp;&nbsp;
-                      </>
+                      </span>
                     ))}

Note: Changed from React fragment to <span> since fragments with keys are less common. If the list is truly stable, using index as key is acceptable here.

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

33-34: Component correctly implements React and Next.js conventions; ESLint verification required before merge.

The component properly uses named React imports (useState, useEffect, useRef, memo from line 3), applies readonly modifiers on all interface props, and follows functional component patterns with memo optimization. Navigation uses Next.js Link component instead of raw <a> tags. Code aligns with React 19.2 and Next.js 16 conventions. Verify ESLint compliance by running npm run lint to confirm the changes pass Next.js Core Web Vitals and React Hooks rules.

components/waves/drops/LightDrop.tsx (1)

2-6: Remove unused import and interface.

The ApiLightDrop import and LightDropProps interface are no longer used since the component doesn't consume any props. This creates a misleading API where callers must pass a drop prop that is completely ignored.

🔎 Proposed fix to complete the refactor
-import { FC } from "react";
-import { ApiLightDrop } from "@/generated/models/ApiLightDrop";
-
-interface LightDropProps {
-  readonly drop: ApiLightDrop;
-}
+import { FC } from "react";
components/waves/drops/winner/DefaultWinnerDrop.tsx (1)

72-84: Fix typo in interface name.

The interface name DefautWinnerDropProps has a typo—it should be DefaultWinnerDropProps (with an 'l') to match the component name DefaultWinnerDrop.

🔎 Proposed fix
-interface DefautWinnerDropProps {
+interface DefaultWinnerDropProps {
   readonly drop: ExtendedDrop;
   readonly showWaveInfo: boolean;
   readonly activeDrop: ActiveDropState | null;
   readonly showReplyAndQuote: boolean;
   readonly location: DropLocation;
   readonly dropViewDropId: string | null;
   readonly onReply: (param: DropInteractionParams) => void;
   readonly onQuote: (param: DropInteractionParams) => void;
   readonly onReplyClick: (serialNo: number) => void;
   readonly onQuoteClick: (drop: ApiDrop) => void;
   readonly onDropContentClick?: ((drop: ExtendedDrop) => void) | undefined;
 }
 
 const DefaultWinnerDrop = ({
   drop,
   showWaveInfo,
   activeDrop,
   location,
   dropViewDropId,
   onReply,
   onQuote,
   onReplyClick,
   onQuoteClick,
   onDropContentClick,
   showReplyAndQuote,
-}: DefautWinnerDropProps) => {
+}: DefaultWinnerDropProps) => {
components/waves/memes/traits/DropdownTrait.tsx (1)

27-32: Refactor to fully controlled component pattern.

This Effect manually syncs external state into an uncontrolled component (line 67 uses defaultValue), which mixes controlled and uncontrolled patterns—a React anti-pattern. This approach fights React's declarative model and can cause subtle bugs.

Based on learnings, remove unnecessary Effects that only sync state. Convert this to a fully controlled component by removing the ref and Effect, then using value instead of defaultValue.

🔎 Proposed refactor to controlled component

Remove the ref (line 24):

-  const selectRef = useRef<HTMLSelectElement>(null);

Remove the Effect (lines 27-32):

-  // Update select value when traits change
-  React.useEffect(() => {
-    const value = (traits[field] as string) || "";
-    if (selectRef.current && value !== selectRef.current.value) {
-      selectRef.current.value = value;
-    }
-  }, [traits, field]);

Update the select element to use value instead of defaultValue and remove the ref (lines 65-69):

     <select
-      ref={selectRef}
-      defaultValue={(traits[field] as string) || ""}
+      value={(traits[field] as string) || ""}
       onChange={handleChange}
       onBlur={handleBlur}
components/nextGen/collections/NextGenArtists.tsx (1)

42-44: Fix missing Effect dependency to satisfy React Hooks ESLint rule.

The fetchResults function is called inside the Effect but not listed in the dependency array, violating the react-hooks/exhaustive-deps rule.

🔎 Proposed fixes

Option 1 (Recommended): Move fetchResults inside the Effect

  useEffect(() => {
+   function fetchResults() {
+     let url = `${publicEnv.API_ENDPOINT}/api/nextgen/collections`;
+     fetchUrl(url).then((response: DBResponse) => {
+       setArtistCollections(
+         response.data.reduce((acc, collection) => {
+           if (
+             !acc.find((a: any) =>
+               areEqualAddresses(a.address, collection.artist_address)
+             )
+           ) {
+             acc.push({
+               address: collection.artist_address,
+               collections: response.data
+                 .filter((c) =>
+                   areEqualAddresses(c.artist_address, collection.artist_address)
+                 )
+                 .sort((a, b) => a.id - b.id),
+             });
+           }
+           return acc;
+         }, [])
+       );
+     });
+   }
    fetchResults();
  }, []);

Then remove the old fetchResults function definition (lines 17-40).

Option 2: Wrap with useCallback

+ import { useEffect, useState, useCallback } from "react";
- function fetchResults() {
+ const fetchResults = useCallback(() => {
    let url = `${publicEnv.API_ENDPOINT}/api/nextgen/collections`;
    fetchUrl(url).then((response: DBResponse) => {
      setArtistCollections(
        response.data.reduce((acc, collection) => {
          if (
            !acc.find((a: any) =>
              areEqualAddresses(a.address, collection.artist_address)
            )
          ) {
            acc.push({
              address: collection.artist_address,
              collections: response.data
                .filter((c) =>
                  areEqualAddresses(c.artist_address, collection.artist_address)
                )
                .sort((a, b) => a.id - b.id),
            });
          }
          return acc;
        }, [])
      );
    });
- }
+ }, []);
  useEffect(() => {
    fetchResults();
- }, []);
+ }, [fetchResults]);

Based on coding guidelines: "Code must satisfy ESLint with Next's Core Web Vitals and React Hooks rules."

components/waves/memes/file-upload/utils/constants.ts (1)

12-15: Update the comment to reflect 200MB limit.

The comment states "100MB" but the actual value is 200 * 1024 * 1024 (200MB). This creates confusion between documentation and implementation.

🔎 Proposed fix
 /**
- * Maximum file size allowed (100MB)
+ * Maximum file size allowed (200MB)
  */
 export const FILE_SIZE_LIMIT: number = 200 * 1024 * 1024;
components/user/stats/activity/tdh-history/UserPageStatsActivityTDHHistoryCharts.tsx (2)

136-141: Critical: Replace random key with stable identifier.

Using getRandomObjectId() as a React key is a critical anti-pattern. Keys must be stable across renders to allow React's reconciliation algorithm to function correctly. Random keys cause React to destroy and recreate components on every render, leading to:

  • Loss of component state
  • Unnecessary DOM operations and poor performance
  • Broken animations and transitions

Since you removed the index parameter in this PR, use dataSet.title instead, which is unique per CHART_CONFIGS.

🔎 Proposed fix
-      {dataSets.map((dataSet) => (
+      {dataSets.map((dataSet) => (
         <UserPageStatsActivityTDHHistoryChart
-          key={getRandomObjectId()}
+          key={dataSet.title}
           data={dataSet}
         />
       ))}

79-132: Replace Effect with useMemo for derived state.

The Effect computes derived state from tdhHistory without performing any side effects. Per coding guidelines, derive this data during render using useMemo instead of useState + useEffect.

As per coding guidelines, "Remove unnecessary Effects; if the Effect only derives state, compute during render instead."

🔎 Proposed refactor
-  const [dataSets, setDataSets] = useState<ChartProps[]>([]);
+  const dataSets = useMemo<ChartProps[]>(() => {
+    if (!tdhHistory.length) {
+      return [];
+    }
+    const tdhHistoryReversed = tdhHistory.toReversed();
+    const tdhLabels = tdhHistoryReversed.map((t) => t.date);
+    return getDataSets({ tdh: tdhHistoryReversed, labels: tdhLabels });
+  }, [tdhHistory]);
 
   const isNumber = (n: any): n is number => typeof n === "number";
 
   const getData = ({
     tdh,
     labels,
     field,
   }: {
     tdh: TDHHistory[];
     labels: Date[];
     field: keyof TDHHistory;
   }): number[] => {
     return labels.map((l) => {
       const tdhItem = tdh.find((t) => t.date === l);
       if (!tdhItem) {
         return 0;
       }
       const value = tdhItem[field];
       return tdhItem && isNumber(value) ? value : 0;
     });
   };
 
   const getDataSets = ({
     tdh,
     labels,
   }: {
     tdh: TDHHistory[];
     labels: Date[];
   }): ChartProps[] => {
     return CHART_CONFIGS.map((config) => {
       return {
         title: config.title,
         labels,
         datasets: config.datasets.map((d) => ({
           label: d.label,
           data: getData({ tdh, labels, field: d.field }),
           backgroundColor: d.color,
           borderColor: d.color,
         })),
       };
     }).filter((c) => c.datasets.some((d) => d.data.some((n) => n > 0)));
   };
-
-  useEffect(() => {
-    if (!tdhHistory.length) {
-      setDataSets([]);
-      return;
-    }
-
-    const tdhHistoryReversed = tdhHistory.toReversed();
-    const tdhLabels = tdhHistoryReversed.map((t) => t.date);
-    setDataSets(getDataSets({ tdh: tdhHistoryReversed, labels: tdhLabels }));
-  }, [tdhHistory]);

Note: You'll need to import useMemo from React.

components/waves/create-wave/outcomes/winners/rows/cic/CreateWaveOutcomesRowCICApprove.tsx (1)

4-8: Incomplete refactor: Remove button is now non-functional.

The removeOutcome prop was removed from the component signature, but the Remove button at lines 48-68 still exists with no onClick handler. This creates a broken user experience where the button appears interactive but does nothing when clicked.

Either:

  1. Add back the removeOutcome callback and wire it to the button's onClick, or
  2. Remove the entire button element if removal functionality is no longer needed
components/waves/create-wave/outcomes/winners/rows/cic/CreateWaveOutcomesRowCICRank.tsx (1)

4-8: Incomplete refactor: Remove button is now non-functional.

The removeOutcome prop was removed from the component signature, but the Remove button at lines 48-68 still exists with no onClick handler. This creates a broken user experience where the button appears interactive but does nothing when clicked.

Either:

  1. Add back the removeOutcome callback and wire it to the button's onClick, or
  2. Remove the entire button element if removal functionality is no longer needed
components/waves/winners/drops/header/WaveWinnersDropHeaderAuthorHandle.tsx (1)

14-24: Apply consistent fallback handling for winner.drop.author.handle across all three usages.

The multiline formatting change is good. However, author.handle is typed as string | null (from ApiProfileMin), so the three usages are inconsistent:

  • Line 15: user={winner.drop.author.handle ?? winner.drop.author.id} — has fallback
  • Line 18: href={/${winner.drop.author.handle}} — no fallback, would create /null if handle is null
  • Line 22: {winner.drop.author.handle} — no fallback, would render undefined text

Apply the same fallback pattern to lines 18 and 22 as used in line 15, or conditionally render the entire component if handle is null.

components/nextGen/collections/collectionParts/NextGenCollectionDetails.tsx (1)

123-323: The ABOUT view displays hardcoded Pebbles content for all collections.

The removal of the unused collection prop is correct. However, NextGenCollectionDetailsAbout renders hardcoded content specific to the Pebbles collection (lines 128, 149, 164, 240, etc.) regardless of which collection is being viewed. This component is used for all collections via the dynamic route app/nextgen/collection/[collection]/[[...view]]/page.tsx, so any user navigating to the ABOUT tab for any NextGen collection will see Pebbles-specific information instead of collection-specific content.

Other views (OVERVIEW, PROVENANCE, TOP_TRAIT_SETS) properly pass and use the collection prop. Either restrict this view to the Pebbles collection, make it collection-aware with dynamic content, or return null for non-Pebbles collections.

🧹 Nitpick comments (28)
components/waves/winners/MemesWaveWinnerDropSmall.tsx (1)

126-133: Replace <img> with <Image /> from next/image.

The <img> element violates Next.js's @next/next/no-img-element ESLint rule. Since this file is already being updated as part of the cleanup, consider migrating to the Image component from next/image to ensure full ESLint compliance.

🔎 Proposed fix using next/image
+import Image from "next/image";
...
-              {drop.author.pfp ? (
-                <img
-                  src={getScaledImageUri(
-                    drop.author.pfp,
-                    ImageScale.W_AUTO_H_50
-                  )}
-                  alt={`${drop.author.handle}'s profile`}
-                  className="tw-size-7 tw-rounded-lg tw-ring-1 tw-ring-white/10 tw-object-cover"
-                />
+              {drop.author.pfp ? (
+                <Image
+                  src={getScaledImageUri(
+                    drop.author.pfp,
+                    ImageScale.W_AUTO_H_50
+                  )}
+                  alt={`${drop.author.handle}'s profile`}
+                  width={28}
+                  height={28}
+                  className="tw-rounded-lg tw-ring-1 tw-ring-white/10 tw-object-cover"
+                />

Note: You may need to adjust width and height based on the actual image dimensions or use fill with a container if dynamic sizing is required.

components/waves/winners/drops/DropContentSmall.tsx (1)

26-29: Consider extracting noop callbacks to preserve referential stability.

The inline empty arrow functions (() => {}) create new function references on each render. If WaveDropContent is memoized, these changing references could defeat its memoization.

🔎 Suggested improvement
+const noop = () => {};
+
 export const DropContentSmall = memo<DropContentSmallProps>(
   ({ drop, onDropClick }) => {
     const [activePartIndex, setActivePartIndex] = useState(0);

     const handleDropClick = useCallback(() => {
       onDropClick(drop);
     }, [drop, onDropClick]);

     return (
       <div>
         <WaveDropContent
           drop={drop}
           activePartIndex={activePartIndex}
           setActivePartIndex={setActivePartIndex}
-          onLongPress={() => {}}
+          onLongPress={noop}
           onDropContentClick={handleDropClick}
-          onQuoteClick={() => {}}
-          setLongPressTriggered={() => {}}
+          onQuoteClick={noop}
+          setLongPressTriggered={noop}
         />
       </div>
     );
   }
 );
components/home/HomeFeed.tsx (1)

47-49: Remove unnecessary Effect that only initializes state.

The useEffect with an empty dependency array is redundant—it only sets activeDrop to null, which is already its initial value from line 23. According to coding guidelines, Effects whose only job is to set state should be removed. This also allows removing the unused useEffect import.

🔎 Proposed fix

Remove the Effect (lines 47–49) and update the import on line 3:

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

And delete:

-  useEffect(() => {
-    setActiveDrop(null);
-  }, []);
-

Based on learnings, unnecessary Effects should be removed when they only derive or sync internal state. Aligning with this guidance and the PR's goal of cleaning up unused code.

components/utils/icons/ClockIcon.tsx (1)

3-35: Consider migrating to FontAwesome for icon consistency.

While the current implementation is correct, the coding guidelines specify using FontAwesome for icons in React components. Consider migrating this custom SVG icon to FontAwesome in a future refactor to align with project standards.

As per coding guidelines, this would improve consistency across the icon system.

components/waves/drops/MediaThumbnail.tsx (1)

25-25: LGTM! React import removal aligns with JSX automatic runtime.

The removal of the explicit React import is correct and follows modern React 19.2 conventions.

Pre-existing issue: <img> element should use Next.js <Image />

Lines 12-16 use a raw <img> element, which violates the Next.js ESLint rule @next/next/no-img-element. Would you like me to open a separate issue to migrate this to <Image /> from next/image?

Based on coding guidelines requiring Next.js <Image /> for all images.

components/waves/create-wave/voting/components/TimeUnitSelector.tsx (2)

22-25: Move constant array outside component scope.

The timeUnitOptions array is static but gets recreated on every render. Define it outside the component to avoid unnecessary allocations.

🔎 Suggested refactor
+const TIME_UNIT_OPTIONS: { value: TimeUnit; label: string }[] = [
+  { value: "minutes", label: "Minutes" },
+  { value: "hours", label: "Hours" },
+];
+
 const TimeUnitSelector = memo(
   ({ value, onUnitChange, id, ariaLabel }: TimeUnitSelectorProps) => {
-    // Options for the time unit dropdown
-    const timeUnitOptions: { value: TimeUnit; label: string }[] = [
-      { value: "minutes", label: "Minutes" },
-      { value: "hours", label: "Hours" },
-    ];

     return (
       <select
         id={id}
         aria-label={ariaLabel}
         className="tw-px-3 tw-py-2 tw-bg-iron-800 tw-text-iron-50 tw-border tw-border-iron-700 tw-rounded-md tw-ml-2"
         value={value}
         onChange={(e) => {
-          // Type assertion needed here as TypeScript can't infer the value is TimeUnit
           const selectedUnit = e.target.value as TimeUnit;
           onUnitChange(selectedUnit);
         }}
         data-testid="time-unit-selector"
       >
-        {timeUnitOptions.map((option) => (
+        {TIME_UNIT_OPTIONS.map((option) => (
           <option key={option.value} value={option.value}>
             {option.label}
           </option>
         ))}
       </select>
     );
   }
 );

21-21: Remove comments per coding guidelines.

The coding guidelines specify that code should be self-explanatory without comments. Both comments can be safely removed as the code is clear without them.

As per coding guidelines, comments should not be included in the code.

Also applies to: 34-34

components/brain/notifications/NotificationsWrapper.tsx (1)

16-30: Consider simplifying redundant optional type syntax.

The type definition uses | undefined after optional properties (e.g., chat?: ... | undefined), which is redundant since the ? operator already permits undefined. While functionally correct, simplifying would improve readability.

🔎 Simplified type definition
 type WaveWithChatScope = ExtendedDrop["wave"] & {
-  chat?:
-    | {
-        scope?:
-          | {
-              group?:
-                | {
-                    is_direct_message?: boolean | undefined;
-                  }
-                | undefined;
-            }
-          | undefined;
-      }
-    | undefined;
+  chat?: {
+    scope?: {
+      group?: {
+        is_direct_message?: boolean;
+      };
+    };
+  };
 };
components/memes/drops/meme-participation-drop/MemeDropActions.tsx (1)

29-31: Remove explanatory comments per coding guidelines.

The comments explain why showVoting is not set. Per the project's coding guidelines, code should be self-explanatory without comments.

As per coding guidelines, code in this project should be self-explanatory and not include comments.

components/profile-activity/filter/ProfileActivityLogsFilterListItem.tsx (1)

17-23: Remove unnecessary Effect and compute state during render.

The useEffect only derives isSelected from selectedItems and itemType. This violates the guideline to avoid Effects for state derivation. Compute directly during render instead.

Based on learnings, remove unnecessary Effects and calculate during render.

🔎 Proposed refactor
-  const [isSelected, setIsSelected] = useState(
-    selectedItems.includes(itemType)
-  );
-
-  useEffect(() => {
-    setIsSelected(selectedItems.includes(itemType));
-  }, [selectedItems]);
+  const isSelected = selectedItems.includes(itemType);
components/memes/drops/MemeWinnerArtistInfo.tsx (1)

20-21: Consider removing the comment per coding guidelines.

The code is self-explanatory, and the coding guidelines specify that comments should be avoided.

As per coding guidelines, code should not include comments.

Proposed change
-  // Get the decision time from the winning context
   const decisionTime = drop.winning_context?.decision_time;
components/nextGen/collections/NextGenArtists.tsx (2)

53-66: LGTM: Unused parameter correctly removed.

The removal of the unused index parameter aligns with the PR objective and improves code clarity.

Optional: Remove redundant type annotation

TypeScript can infer the parameter type from artistCollections, making the explicit annotation unnecessary:

-     (ac: { address: string; collections: NextGenCollection[] }) => {
+     (ac) => {

21-37: Replace any type with specific type for better type safety.

The accumulator type can be explicitly defined instead of using any.

🔎 Proposed fix
      setArtistCollections(
        response.data.reduce((acc, collection) => {
          if (
-           !acc.find((a: any) =>
+           !acc.find((a) =>
              areEqualAddresses(a.address, collection.artist_address)
            )
          ) {
            acc.push({
              address: collection.artist_address,
              collections: response.data
                .filter((c) =>
                  areEqualAddresses(c.artist_address, collection.artist_address)
                )
                .sort((a, b) => a.id - b.id),
            });
          }
          return acc;
-       }, [])
+       }, [] as { address: string; collections: NextGenCollection[] }[])
      );
components/drops/view/item/content/nft-tag/DropListItemContentNftDetails.tsx (1)

16-20: Consider replacing <img> with Next.js <Image />.

Per coding guidelines, <img> elements should be replaced with <Image /> from next/image to comply with the @next/next/no-img-element ESLint rule. While this is outside the scope of the current PR, it would improve consistency with Next.js best practices.

🔎 Proposed refactor
+import Image from "next/image";
+
 import { ReferencedNft } from "@/entities/IDrop";
     <div className="tw-gap-x-2 tw-flex tw-items-center">
       {image && (
-        <img
+        <Image
           alt="Seize"
           src={getScaledImageUri(image, ImageScale.W_AUTO_H_50)}
           className="tw-flex-shrink-0 tw-h-4 tw-w-4 tw-object-contain"
+          width={16}
+          height={16}
         />
       )}

As per coding guidelines, Next.js <Image /> component should be used for images.

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

123-131: Consider migrating to Next.js <Image> component.

The component uses an <img> tag for the author profile picture. Per coding guidelines, Next.js <Image> should be used instead to comply with the @next/next/no-img-element ESLint rule and gain automatic optimization benefits.

Note: This is pre-existing code, not introduced in this PR, so it can be addressed separately if desired.

🔎 Proposed refactor to use Next.js Image

Add the Image import at the top of the file:

+import Image from "next/image";

Then replace the img tag:

-              {drop.author.pfp ? (
-                <img
-                  src={getScaledImageUri(
-                    drop.author.pfp,
-                    ImageScale.W_AUTO_H_50
-                  )}
-                  alt={`${drop.author.handle}'s profile`}
-                  className="tw-size-7 tw-rounded-lg tw-ring-1 tw-ring-white/10 tw-object-cover"
-                />
-              ) : (
-                <div className="tw-size-7 tw-rounded-lg tw-ring-1 tw-ring-white/10 tw-bg-iron-800" />
-              )}
+              {drop.author.pfp ? (
+                <Image
+                  src={getScaledImageUri(
+                    drop.author.pfp,
+                    ImageScale.W_AUTO_H_50
+                  )}
+                  alt={`${drop.author.handle}'s profile`}
+                  className="tw-size-7 tw-rounded-lg tw-ring-1 tw-ring-white/10 tw-object-cover"
+                  width={28}
+                  height={28}
+                />
+              ) : (
+                <div className="tw-size-7 tw-rounded-lg tw-ring-1 tw-ring-white/10 tw-bg-iron-800" />
+              )}
components/manifoldMinting/ManifoldMintingWidget.tsx (1)

83-91: LGTM! Unused index parameter correctly removed.

The index parameter was not referenced in the map body, so its removal is appropriate and aligns with the PR objective.

Optional: Consider using .forEach() instead of .map()

Since the iteration is used purely for side effects (pushing to params) and the returned array is discarded, .forEach() would be more semantically appropriate than .map():

-merkleProofs.map((mp) => {
+merkleProofs.forEach((mp) => {
   params.push({
     address: props.proxy as `0x${string}`,
     abi: props.abi,
     chainId: MANIFOLD_NETWORK.id,
     functionName: "checkMintIndex",
     args: [props.contract, props.claim.instanceId, mp.value],
   });
 });
components/waves/drops/DropNotFound.tsx (1)

1-3: Consider removing the JSDoc comment.

The component name DropNotFound is self-explanatory. As per coding guidelines, comments should be avoided when code is self-documenting.

Proposed refactor
-/**
- * Component to show when a drop is not found
- */
 export default function DropNotFound() {
components/waves/winners/WaveWinnersSmall.tsx (1)

62-67: Unnecessary non-null assertion on a guarded value.

On line 65, the non-null assertion (!) is redundant since the condition on line 64 already guarantees decisionPoints.length > 0, and optional chaining (?.) already handles the case. Consider removing the ! for cleaner code:

🔎 Suggested fix
     useEffect(() => {
       if (decisionPoints?.length > 0 && !activeDecisionPoint) {
-        setActiveDecisionPoint(decisionPoints[0]?.id!);
+        setActiveDecisionPoint(decisionPoints[0].id);
       }
     }, [decisionPoints, activeDecisionPoint]);
components/memes/drops/meme-participation-drop/MemeDropArtistInfo.tsx (2)

48-51: Minor redundancy in fallback logic.

Since line 48 already checks that drop.author?.handle is truthy, the fallback ?? drop.author.id on line 50 will never be executed. Consider simplifying to just user={drop.author.handle}.

🔎 Proposed simplification
-              <UserProfileTooltipWrapper
-                user={drop.author.handle ?? drop.author.id}
-              >
+              <UserProfileTooltipWrapper user={drop.author.handle}>

96-96: Remove comment per coding guidelines.

As per coding guidelines, comments should be avoided when code is self-explanatory. The ArtistPreviewModal component name clearly indicates its purpose.

🔎 Proposed fix
-
-      {/* Artist Preview Modal */}
       <ArtistPreviewModal

Based on coding guidelines: "Do not include any comments in the code; it should be self-explanatory"

components/waves/drops/participation/ratings/ParticipationDropRatingsVoterSection.tsx (1)

33-40: Consider migrating to Next.js <Image /> component.

The standard HTML <img> tag should be replaced with Next.js <Image /> to comply with ESLint rule @next/next/no-img-element and leverage automatic image optimization.

📦 Suggested migration to Next.js Image

Add the Image import at the top of the file:

+import Image from "next/image";

Then replace the <img> tag:

-                  <img
-                    src={getScaledImageUri(
-                      rater.profile.pfp,
-                      ImageScale.W_AUTO_H_50
-                    )}
-                    alt={`${rater.profile.handle}'s avatar`}
-                    className={`tw-h-5 tw-w-5 tw-rounded-md tw-ring-1 tw-object-cover ${theme.ring} tw-bg-iron-900`}
-                  />
+                  <Image
+                    src={getScaledImageUri(
+                      rater.profile.pfp,
+                      ImageScale.W_AUTO_H_50
+                    )}
+                    alt={`${rater.profile.handle}'s avatar`}
+                    width={20}
+                    height={20}
+                    className={`tw-h-5 tw-w-5 tw-rounded-md tw-ring-1 tw-object-cover ${theme.ring} tw-bg-iron-900`}
+                  />

Based on coding guidelines and learnings.

components/rememes/Rememes.tsx (2)

142-145: Consider using Next.js <Link> component for internal navigation.

The <a> tag causes full page reloads. Replace with <Link> from next/link for client-side navigation and better performance, per Next.js best practices.

Proposed refactor

Import Link at the top of the file:

 import Image from "next/image";
+import Link from "next/link";
 import { usePathname, useRouter, useSearchParams } from "next/navigation";

Then replace the anchor tag:

-        <a
-          href={`/rememes/${rememe.contract}/${rememe.id}`}
+        <Link
+          href={`/rememes/${rememe.contract}/${rememe.id}`}
           className="decoration-none scale-hover"
         >
           <Container fluid>
             ...
           </Container>
-        </a>
+        </Link>

254-259: Prefer router.push() over window.location.href for internal navigation.

Since router from useRouter() is already available (line 44), use router.push("/rememes/add") instead of window.location.href for client-side navigation without full page reload.

Proposed refactor
                 <Button
                   className="seize-btn btn-white d-flex align-items-center justify-content-center gap-2 w-100 w-sm-auto"
                   onClick={() => {
-                    window.location.href = "/rememes/add";
+                    router.push("/rememes/add");
                   }}
                 >
components/distribution-plan-tool/review-distribution-plan/table/ReviewDistributionPlanTableHeader.tsx (1)

124-150: LGTM!

The className formatting changes improve readability without affecting functionality.

components/waves/drops/winner/WinnerDropBadge.tsx (2)

1-1: Consider using direct FC import instead of React namespace.

Per coding guidelines, prefer direct named imports from React over namespace usage.

🔎 Proposed refactor
-import React from "react";
+import { FC } from "react";
 import { faClock } from "@fortawesome/free-regular-svg-icons";
 import { faTrophy } from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-const WinnerDropBadge: React.FC<WinnerDropBadgeProps> = ({
+const WinnerDropBadge: FC<WinnerDropBadgeProps> = ({
   rank,
   position = 1,
   decisionTime,

Based on learnings, prefer direct named imports.

Also applies to: 13-13


19-25: Optional: String type guard is unreachable code.

The type guard on lines 23-24 checks for string type, but based on the interface definitions (rank: number | null, position: number), effectiveRank can only ever be a number. This check will never be true and could be simplified.

🔎 Proposed simplification
   const effectiveRank = rank !== null && rank !== undefined ? rank : position;
   if (!effectiveRank) return null;
 
-  const rankNumber =
-    typeof effectiveRank === "string"
-      ? parseInt(effectiveRank, 10)
-      : effectiveRank;
+  const rankNumber = effectiveRank;
components/rememes/RememeAddPage.tsx (2)

357-360: Good removal of unused parameter, but consider using a stable key.

The removal of the unused index parameter aligns with the PR objective. However, the code uses getRandomObjectId() as a React key, which generates a new ID on every render. This causes React to recreate DOM elements unnecessarily.

🔎 Suggested refactor for stable key

Since the index was already available (before this PR removed it), consider using it for the key, or use the error message itself if errors are unique:

-submissionResult.errors.map((e) => (
-  <Col xs={12} className="pt-2" key={getRandomObjectId()}>
+submissionResult.errors.map((e, index) => (
+  <Col xs={12} className="pt-2" key={`error-${index}`}>
    {e}
  </Col>
))}

63-108: Consider refactoring effect to useMemo.

This effect only derives the checkList state from addRememe and userTDH without performing side effects. Per React best practices and learnings, derived state should be computed during render using useMemo rather than in an effect.

Based on learnings, effects should be reserved for synchronization with external systems, not for deriving state.

🔎 Suggested refactor using useMemo
-useEffect(() => {
+const checkList = useMemo(() => {
   const mychecklist: CheckList[] = [];
   if (addRememe) {
     if (!seizeSettings?.rememes_submission_tdh_threshold) {
       mychecklist.push({
         status: false,
         note: "Something went wrong fetching global settings",
       });
     } else {
       const isDeployer = areEqualAddresses(
         addRememe.contract.contractDeployer,
         address
       );

       if (isDeployer) {
         mychecklist.push({
           status: true,
           note: "Rememe can be added (Rememe Contract Deployer)",
         });
       } else {
         if (!userTDH) {
           mychecklist.push({
             status: false,
             note: "You need to have some TDH before you can add Rememes",
           });
         } else {
           mychecklist.push({
             status:
               userTDH.boosted_tdh >=
               seizeSettings.rememes_submission_tdh_threshold,
             note: `You need ${numberWithCommas(
               seizeSettings.rememes_submission_tdh_threshold
             )} TDH to add ${
               addRememe.nfts.length > 1 ? `these Rememes` : `this Rememe`
             }${
               userTDH
                 ? ` (you have ${numberWithCommas(userTDH.boosted_tdh)} TDH)`
                 : ``
             }`,
           });
         }
       }
     }
   }
-  setCheckList(mychecklist);
+  return mychecklist;
 }, [addRememe, userTDH]);

Then remove the const [checkList, setCheckList] = useState<CheckList[]>([]); line and any setCheckList([]) calls, as the value is now computed.

Comment thread components/waves/drops/LightDrop.tsx
@simo6529 simo6529 merged commit 1985b45 into main Jan 3, 2026
10 of 11 checks passed
@simo6529 simo6529 deleted the fix-noUnusedParameters branch January 3, 2026 14:33
@coderabbitai coderabbitai Bot mentioned this pull request Jan 8, 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