Skip to content

Meme Submissions - Additional Fields#1728

Merged
prxt6529 merged 7 commits intomainfrom
meme-submissions-additional-fields
Jan 13, 2026
Merged

Meme Submissions - Additional Fields#1728
prxt6529 merged 7 commits intomainfrom
meme-submissions-additional-fields

Conversation

@prxt6529
Copy link
Copy Markdown
Collaborator

@prxt6529 prxt6529 commented Jan 12, 2026

Summary by CodeRabbit

  • New Features
    • ENS-aware address input/display added across forms; new PaymentConfig, preview image upload, and "About the Artist" field in submission flows.
  • Refactor
    • Submission and drop-detail UIs reorganized to surface preview images and supporting media; per-entry ENS validation/loading and unified address display integrated.
  • Tests
    • New and updated unit tests for ENS address input, payment config, media upload, and submission metadata handling.

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

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

coderabbitai Bot commented Jan 12, 2026

📝 Walkthrough

Walkthrough

Adds ENS-aware input and display components, integrates ENS handling into wallet/payment/airdrop UIs, and extends memes submission metadata with about_artist and preview_image, propagating those through forms, uploads, mutation transformation, drop display, and tests.

Changes

Cohort / File(s) Summary
ENS Address Components
components/utils/input/ens-address/EnsAddressInput.tsx, components/utils/input/ens-address/EnsAddressDisplay.tsx, __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
New EnsAddressInput (wraps useEnsResolution, emits address/value/loading/error callbacks) and EnsAddressDisplay (resolves ENS names for addresses, shows loading/resolved states). Unit tests for input behaviors added.
Wallet & Delegation
components/delegation/walletChecker/WalletChecker.tsx, __tests__/components/walletChecker.test.tsx
Replaced direct ENS hook flow with EnsAddressInput; consolidated wallet input/address/loading state; updated tests to mock EnsAddressInput.
Submission Types & Hook API
components/waves/memes/submission/types/OperationalData.ts, components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts, __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
Added about_artist and preview_image to types and initial operational data; useArtworkSubmissionForm now exposes setAboutArtist; tests updated for ABOUT_ARTIST handling.
Submission Container / Steps
components/waves/memes/submission/MemesArtSubmissionContainer.tsx, components/waves/memes/submission/steps/AdditionalInfoStep.tsx
Extended container and step props to include paymentInfo, supportingMedia, aboutArtist, previewImage, preview requirement flags and related handlers; updated validation and step wiring.
Additional Media Upload
components/waves/memes/submission/components/AdditionalMediaUpload.tsx, __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
Replaced artworkCommentaryMedia with supportingMedia; added preview image upload flow, aboutArtist field, new callbacks, reactive parent updates, and preview-related tests.
Payment & Airdrop Configs
components/waves/memes/submission/components/PaymentConfig.tsx, components/waves/memes/submission/components/AirdropConfig.tsx, __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
New PaymentConfig component using EnsAddressInput; AirdropConfig refactored to per-entry ENS loading/error state with EnsAddressInput; payment input tests added.
Mutation Transformation
components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
Reworked transformToApiRequest to assemble extra fields (payment_info, commentary, about_artist, additional_media, allowlist/airdrop) into operationalMetadata before merging into final metadata.
Drop Panels & Details
components/waves/drop/WaveDropAdditionalInfo.tsx, components/waves/drop/MemesSingleWaveDropInfoPanel.tsx, components/waves/drop/SingleWaveDropTechnicalDetails.tsx
Added preview_image parsing/rendering and About the Artist/commentary sections; replaced raw addresses with EnsAddressDisplay; adjusted layout and copy UI.
Minor UI Utilities
components/waves/memes/traits/TraitWrapper.tsx, components/waves/memes/submission/components/AllowlistBatchManager.tsx
Added padding override behavior in TraitWrapper; minor spacing and required-label tweak in AllowlistBatchManager.
Tests (general)
__tests__/components/waves/memes/submission/**, various new/updated tests
Tests updated/added across submission components to cover new fields (about_artist, preview_image), preview/media behaviors, and new PaymentConfig/Airdrop flows.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant EnsInput as EnsAddressInput
    participant ResolverHook as useEnsResolution
    participant ENS as ENS Resolver
    participant Parent as Parent Component

    User->>EnsInput: Type address or ENS name
    EnsInput->>EnsInput: update inputValue
    EnsInput->>Parent: onValueChange(inputValue)
    alt input ends with .eth
        EnsInput->>ResolverHook: trigger lookup
        ResolverHook->>ENS: network lookup
        ENS-->>ResolverHook: resolved address or error
        ResolverHook-->>EnsInput: address, loading, error
        EnsInput->>Parent: onLoadingChange(isLoading)
        alt resolved
            EnsInput->>Parent: onAddressChange(resolvedAddress)
            EnsInput->>Parent: onError(false)
        else failed
            EnsInput->>Parent: onError(true)
        end
    else raw 0x address
        EnsInput->>Parent: onAddressChange(rawAddress)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • ragnep
  • simo6529

"🐰 I hopped through code with glee,
ENS names now find the key,
Artist bios and preview light,
Media uploads take their flight,
Hooray — small rabbit cheers tonight!"

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 'Meme Submissions - Additional Fields' accurately summarizes the primary change: adding new fields (about_artist, preview_image, payment_info) and reorganizing submission workflows for meme artwork submissions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
components/waves/memes/submission/components/AllowlistBatchManager.tsx (1)

99-99: Typo: tw-truncat should be tw-truncate.

This will prevent the text truncation styling from being applied to the Token IDs input.

🔧 Proposed fix
-                  className={`tw-truncat tw-form-input tw-w-full tw-rounded-lg tw-border-0 tw-bg-iron-900 tw-py-3 tw-pl-4 tw-pr-11 tw-text-sm tw-text-iron-100 tw-outline-none tw-ring-1 ${
+                  className={`tw-truncate tw-form-input tw-w-full tw-rounded-lg tw-border-0 tw-bg-iron-900 tw-py-3 tw-pl-4 tw-pr-11 tw-text-sm tw-text-iron-100 tw-outline-none tw-ring-1 ${
🤖 Fix all issues with AI agents
In
@__tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx:
- Line 14: The test is querying for a placeholder that doesn't match what
PaymentConfig passes to EnsAddressInput; update the three assertions in
PaymentConfig.test.tsx that call screen.getByPlaceholderText("0x...") to use the
actual placeholder string used by the component (e.g., "0x... or ENS") or
otherwise match it (e.g., a partial/regex match) so the queries align with
PaymentConfig -> EnsAddressInput.

In
@__tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx:
- Around line 67-72: The object literal in the test setup for
MemesArtSubmissionContainer has a duplicated property named setPaymentInfo
(defined twice), so remove the redundant second setPaymentInfo entry from the
props object used in
__tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
so only one mock function remains (keep a single jest.fn() for setPaymentInfo
alongside the other setters like setAllowlistBatches, setAdditionalMedia,
setCommentary, and setAboutArtist).

In @components/utils/input/ens-address/EnsAddressInput.tsx:
- Around line 41-43: The useEffect block that calls setInputValue(value) is
redundant because the useEnsResolution hook already syncs initialValue/value to
inputValue; remove the useEffect that depends on [value, setInputInputValue]
(the effect that calls setInputValue) so state updates are driven solely by
useEnsResolution and avoid duplicate updates to inputValue.
🧹 Nitpick comments (17)
components/waves/memes/submission/components/AllowlistBatchManager.tsx (2)

3-3: Prefer direct named imports from React over namespace usage.

As per coding guidelines, use direct named imports instead of React. namespace.

♻️ Proposed refactor
-import React, { useCallback } from "react";
+import { FC, memo, useCallback } from "react";

Then update the component definition:

-const AllowlistBatchManager: React.FC<AllowlistBatchManagerProps> = ({
+const AllowlistBatchManager: FC<AllowlistBatchManagerProps> = ({

And the export:

-export default React.memo(AllowlistBatchManager);
+export default memo(AllowlistBatchManager);

Also applies to: 17-17, 134-134


59-59: Remove inline comments per coding guidelines.

The coding guidelines specify that code should be self-explanatory without comments. The component structure and variable names already convey the purpose clearly.

Also applies to: 82-82, 107-107, 121-121

__tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx (1)

30-200: Good test coverage with one optional callback not tested.

The test suite thoroughly covers rendering, input handling, and all major callbacks (onAddressChange, onLoadingChange, onError). Tests follow the AAA pattern and are well-isolated.

Consider adding a test for the onValueChange optional callback if it's used in production code.

components/delegation/walletChecker/WalletChecker.tsx (1)

67-69: State management could drift if input value synchronization is needed elsewhere.

walletInputValue is initialized but never updated when the user types (no onValueChange handler). This is fine if you only need the resolved address for form submission, but if other parts of the component need the current input text, consider adding:

onValueChange={setWalletInputValue}

The Clear button works correctly because the value prop change triggers the internal setInputValue in EnsAddressInput.

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

297-299: Consider using EnsAddressDisplay for contract addresses for consistency.

Payment addresses and airdrop addresses now use EnsAddressDisplay, but allowlist contract addresses still render raw text. While contracts typically don't have ENS names, some do (e.g., uniswap.eth). Consider wrapping with EnsAddressDisplay for consistency, as it gracefully falls back to the raw address when no ENS name exists.

♻️ Optional: Use EnsAddressDisplay for contract addresses
-                            <div className="tw-line-clamp-1 tw-break-all tw-font-mono tw-text-xs tw-font-medium tw-text-iron-200">
-                              {batch.contract}
-                            </div>
+                            <div className="tw-line-clamp-1 tw-break-all tw-font-mono tw-text-xs tw-font-medium tw-text-iron-200">
+                              <EnsAddressDisplay address={batch.contract} />
+                            </div>
components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts (2)

90-93: Empty payment_info will be serialized to metadata.

payment_info is now unconditionally pushed when operationalData exists. If payment_address is empty, the metadata will contain {"payment_address":""}. Consider adding a guard to avoid storing empty payment info.

♻️ Add conditional check for non-empty payment address
-    metadata.push({
-      data_key: "payment_info",
-      data_value: JSON.stringify(operationalData.payment_info),
-    });
+    if (operationalData.payment_info?.payment_address?.trim()) {
+      metadata.push({
+        data_key: "payment_info",
+        data_value: JSON.stringify(operationalData.payment_info),
+      });
+    }

118-126: Empty commentary and about_artist will be stored in metadata.

Both fields are pushed unconditionally when operationalData exists. This stores empty strings in metadata when users don't provide values. Consider guarding against empty values for consistency with how airdrop_config and allowlist_batches are handled.

♻️ Add guards for non-empty values
-    metadata.push({
-      data_key: "commentary",
-      data_value: operationalData.commentary,
-    });
-
-    metadata.push({
-      data_key: "about_artist",
-      data_value: operationalData.about_artist,
-    });
+    if (operationalData.commentary?.trim()) {
+      metadata.push({
+        data_key: "commentary",
+        data_value: operationalData.commentary,
+      });
+    }
+
+    if (operationalData.about_artist?.trim()) {
+      metadata.push({
+        data_key: "about_artist",
+        data_value: operationalData.about_artist,
+      });
+    }
components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts (1)

623-646: Bio fetch may overwrite user edits if profile changes or component remounts.

This effect fetches the user's bio statement and sets about_artist whenever connectedProfile.handle changes. If a user has already edited the about_artist field and then disconnects/reconnects their wallet, their edits could be overwritten by the fetched bio.

Consider tracking whether the user has manually edited the field and only auto-populate if untouched.

♻️ Track manual edits to prevent overwriting
+  const hasManuallyEditedAboutArtist = useRef(false);
+
   useEffect(() => {
     const handle = connectedProfile?.handle;
-    if (!handle) return;
+    if (!handle || hasManuallyEditedAboutArtist.current) return;

     commonApiFetch<CicStatement[]>({
       endpoint: `profiles/${handle}/cic/statements`,
     })
       .then((statements) => {
         // ... existing logic ...
       })
       .catch((error) => {
         console.error("[useArtworkSubmissionForm] Failed to fetch bio", error);
       });
   }, [connectedProfile?.handle]);

+  const setAboutArtist = useCallback(
+    (aboutArtist: string) => {
+      hasManuallyEditedAboutArtist.current = true;
+      dispatch({ type: "SET_ABOUT_ARTIST", payload: aboutArtist });
+    },
+    [dispatch]
+  );
__tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx (1)

5-9: Consider resetting mock between tests.

The defaultProps.onPaymentInfoChange mock is shared across tests but never cleared. If test order matters or tests are added later, stale call counts could cause false positives/negatives.

Proposed fix
 describe("PaymentConfig", () => {
   const defaultProps = {
     paymentInfo: { payment_address: "" },
     onPaymentInfoChange: jest.fn(),
   };

+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
components/waves/memes/submission/components/PaymentConfig.tsx (1)

30-35: paymentInfo dependency may cause stale closure or excessive callback recreation.

Including paymentInfo in the dependency array means handleAddressChange is recreated whenever the address changes. Since EnsAddressInput receives this callback via onAddressChange, it could trigger unnecessary effects. Consider using a functional update pattern or removing paymentInfo from dependencies if only payment_address is being set.

Proposed fix using callback ref pattern
   const handleAddressChange = useCallback(
     (resolvedAddress: string) => {
-      onPaymentInfoChange({ ...paymentInfo, payment_address: resolvedAddress });
+      onPaymentInfoChange((prev) => ({ ...prev, payment_address: resolvedAddress }));
     },
-    [paymentInfo, onPaymentInfoChange]
+    [onPaymentInfoChange]
   );

This requires the parent to support functional updates in onPaymentInfoChange. Alternatively, if PaymentInfo only has payment_address, simply pass the object directly without spreading.

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

294-300: Replace <img> with <Image /> from next/image.

As per coding guidelines, <img> elements should be replaced with Next.js <Image /> component for optimization benefits and ESLint compliance (@next/next/no-img-element).

Proposed fix
+import Image from "next/image";
 ...
             <div className="tw-flex tw-h-full tw-w-full tw-items-center tw-justify-center">
-              <img
+              <Image
                 src={artworkMedia.url}
                 alt={title}
-                className="tw-max-h-full tw-max-w-full tw-object-contain"
+                fill
+                className="tw-object-contain"
+                sizes="100vw"
               />
             </div>

Note: The parent div may need tw-relative for the fill prop to work correctly.

__tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx (1)

40-56: Consider adding test for onAboutArtistChange callback.

The test suite covers onArtworkCommentaryChange but doesn't test the new onAboutArtistChange callback. For completeness, consider adding a similar test.

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

165-170: Empty caption track is a workaround, not actual accessibility.

The inline VTT track (data:text/vtt,WEBVTT) satisfies linting rules but provides no meaningful captions for users who need them. If actual captions aren't available, consider adding a comment noting this is intentional, or plan to support real captions in the future.

Is there a plan to support actual video captions for uploaded media? If not, this workaround is acceptable but worth documenting.

components/waves/memes/submission/MemesArtSubmissionContainer.tsx (2)

80-84: Use console.log or remove debug logging.

console.warn is typically reserved for warnings. Phase change logging is informational and should use console.log, or be removed entirely if it's debug code.

Suggested fix
  const handlePhaseChange = useCallback((phase: SubmissionPhase) => {
-   console.warn(`Submission phase changed to: ${phase}`);
+   console.log(`Submission phase changed to: ${phase}`);
  }, []);

143-160: Extract IIFE into useMemo for clarity and to avoid recalculating on every render.

The IIFE computes derived state and runs on every render. Using useMemo makes the intent clearer and avoids unnecessary recalculation when dependencies haven't changed. As per coding guidelines, prefer useMemo for deriving state.

Suggested refactor
-  const previewRequiredMediaType = (() => {
-    const getMediaTypeLabel = (mimeType: string): string | null => {
-      if (mimeType.startsWith("video/")) return "Video";
-      if (mimeType === "text/html") return "HTML";
-      if (mimeType === "model/gltf-binary") return "GLB";
-      return null;
-    };
-
-    if (form.mediaSource === "upload" && form.selectedFile) {
-      return getMediaTypeLabel(form.selectedFile.type);
-    }
-    if (form.mediaSource === "url" && form.isExternalMediaValid) {
-      return getMediaTypeLabel(form.externalMediaMimeType);
-    }
-    return null;
-  })();
+  const previewRequiredMediaType = useMemo(() => {
+    const getMediaTypeLabel = (mimeType: string): string | null => {
+      if (mimeType.startsWith("video/")) return "Video";
+      if (mimeType === "text/html") return "HTML";
+      if (mimeType === "model/gltf-binary") return "GLB";
+      return null;
+    };
+
+    if (form.mediaSource === "upload" && form.selectedFile) {
+      return getMediaTypeLabel(form.selectedFile.type);
+    }
+    if (form.mediaSource === "url" && form.isExternalMediaValid) {
+      return getMediaTypeLabel(form.externalMediaMimeType);
+    }
+    return null;
+  }, [
+    form.mediaSource,
+    form.selectedFile,
+    form.isExternalMediaValid,
+    form.externalMediaMimeType,
+  ]);

Also add useMemo to the imports on line 9:

-import { useCallback, useEffect } from "react";
+import { useCallback, useEffect, useMemo } from "react";
components/waves/memes/submission/components/AdditionalMediaUpload.tsx (2)

33-44: Unused props supportingMedia and previewImage — consider removing or implementing initialization.

The supportingMedia prop is received but never used, and previewImage is aliased to _previewImage but also unused. The component manages its own upload state internally and syncs back to the parent via callbacks. If pre-population from existing values isn't needed, consider removing these props from the interface to avoid confusion.

If props should be removed
 interface AdditionalMediaUploadProps {
-  readonly supportingMedia: string[];
   readonly artworkCommentary: string;
   readonly aboutArtist: string;
-  readonly previewImage: string;
   readonly requiresPreviewImage: boolean;
   readonly previewRequiredMediaType: string | null;
   readonly onSupportingMediaChange: (media: string[]) => void;
   readonly onPreviewImageChange: (url: string) => void;
   readonly onArtworkCommentaryChange: (commentary: string) => void;
   readonly onAboutArtistChange: (aboutArtist: string) => void;
   readonly errors?: {
-    supportingMedia?: string;
-    previewImage?: string;
     artworkCommentary?: string;
     aboutArtist?: string;
   };
 }

And remove from destructuring:

 const AdditionalMediaUpload: FC<AdditionalMediaUploadProps> = ({
   artworkCommentary,
   aboutArtist,
-  previewImage: _previewImage,
   requiresPreviewImage,
   previewRequiredMediaType,
   onSupportingMediaChange,
   onPreviewImageChange,
   onArtworkCommentaryChange,
   onAboutArtistChange,
   errors,
 }) => {

Please verify whether initialization from existing media URLs is a planned feature. If so, the component would need logic to populate the upload hooks with pre-existing items on mount.


54-77: Consider calling parent callbacks directly in upload completion instead of syncing via Effects.

Per coding guidelines, Effects that only sync derived state should be avoided. The current pattern uses useEffect to sync mediaServerUrls and previewServerUrl to the parent. This works but adds indirection. Consider modifying useMediaUpload to accept an onComplete callback, or calling onSupportingMediaChange/onPreviewImageChange directly when uploads finish.

That said, if modifying the hook is out of scope for this PR, the current implementation with refs to prevent duplicate calls is acceptable.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8fdfd4f and d735cb8.

📒 Files selected for processing (21)
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/delegation/walletChecker/WalletChecker.tsx
  • components/utils/input/ens-address/EnsAddressDisplay.tsx
  • components/utils/input/ens-address/EnsAddressInput.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • components/waves/memes/submission/MemesArtSubmissionContainer.tsx
  • components/waves/memes/submission/components/AdditionalMediaUpload.tsx
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
  • components/waves/memes/submission/steps/AdditionalInfoStep.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/waves/memes/traits/TraitWrapper.tsx
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

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

**/*.{ts,tsx,js,jsx}: Remove unnecessary Effects. If the Effect's only job is to derive or sync internal state, calculate during render or use useMemo instead.
Use useEffectEvent for non-reactive logic inside Effects to read the latest props/state without turning them into dependencies or causing unnecessary re-runs.
Use explicit caching with "use cache" directive at the top of Server Components, routes, or functions. Configure cacheComponents: true in next.config.ts as needed.

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

Files:

  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/utils/input/ens-address/EnsAddressInput.tsx
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/utils/input/ens-address/EnsAddressDisplay.tsx
  • components/waves/memes/traits/TraitWrapper.tsx
  • components/waves/memes/submission/MemesArtSubmissionContainer.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/steps/AdditionalInfoStep.tsx
  • components/delegation/walletChecker/WalletChecker.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/waves/memes/submission/components/AdditionalMediaUpload.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

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

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

Files:

  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/utils/input/ens-address/EnsAddressInput.tsx
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/utils/input/ens-address/EnsAddressDisplay.tsx
  • components/waves/memes/traits/TraitWrapper.tsx
  • components/waves/memes/submission/MemesArtSubmissionContainer.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • components/waves/memes/submission/steps/AdditionalInfoStep.tsx
  • components/delegation/walletChecker/WalletChecker.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/waves/memes/submission/components/AdditionalMediaUpload.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

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

Files:

  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/utils/input/ens-address/EnsAddressInput.tsx
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/utils/input/ens-address/EnsAddressDisplay.tsx
  • components/waves/memes/traits/TraitWrapper.tsx
  • components/waves/memes/submission/MemesArtSubmissionContainer.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/steps/AdditionalInfoStep.tsx
  • components/delegation/walletChecker/WalletChecker.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/waves/memes/submission/components/AdditionalMediaUpload.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

Files:

  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/utils/input/ens-address/EnsAddressInput.tsx
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/utils/input/ens-address/EnsAddressDisplay.tsx
  • components/waves/memes/traits/TraitWrapper.tsx
  • components/waves/memes/submission/MemesArtSubmissionContainer.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • components/waves/memes/submission/steps/AdditionalInfoStep.tsx
  • components/delegation/walletChecker/WalletChecker.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/waves/memes/submission/components/AdditionalMediaUpload.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

Files:

  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/utils/input/ens-address/EnsAddressInput.tsx
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/utils/input/ens-address/EnsAddressDisplay.tsx
  • components/waves/memes/traits/TraitWrapper.tsx
  • components/waves/memes/submission/MemesArtSubmissionContainer.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/steps/AdditionalInfoStep.tsx
  • components/delegation/walletChecker/WalletChecker.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/waves/memes/submission/components/AdditionalMediaUpload.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/utils/input/ens-address/EnsAddressInput.tsx
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/utils/input/ens-address/EnsAddressDisplay.tsx
  • components/waves/memes/traits/TraitWrapper.tsx
  • components/waves/memes/submission/MemesArtSubmissionContainer.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/steps/AdditionalInfoStep.tsx
  • components/delegation/walletChecker/WalletChecker.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/waves/memes/submission/components/AdditionalMediaUpload.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/utils/input/ens-address/EnsAddressInput.tsx
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/utils/input/ens-address/EnsAddressDisplay.tsx
  • components/waves/memes/traits/TraitWrapper.tsx
  • components/waves/memes/submission/MemesArtSubmissionContainer.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/steps/AdditionalInfoStep.tsx
  • components/delegation/walletChecker/WalletChecker.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/waves/memes/submission/components/AdditionalMediaUpload.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Run npm run test to execute all Jest tests and enforce ≥80% line coverage for files changed since main. Tests must pass and coverage threshold must be met before completing any task.

Enforce ≥ 80% line coverage for files changed since main by running npm run test

Files:

  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
**/{__tests__,*.test.{tsx,ts}}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
**/*.{test,spec}.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Mock external dependencies and APIs in tests

Files:

  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
**/*.{ts,js}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • components/waves/memes/submission/types/OperationalData.ts
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
🧠 Learnings (13)
📚 Learning: 2025-12-30T14:31:53.006Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:53.006Z
Learning: Fix issues with modernization aligned to React 19.2, React Compiler, and Next.js 16 conventions. Do not add `// eslint-disable` comments unless explicitly instructed.

Applied to files:

  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
📚 Learning: 2025-12-30T14:32:19.360Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.360Z
Learning: Applies to **/*.{tsx,ts} : Use TypeScript with React functional components and hooks

Applied to files:

  • components/waves/memes/submission/components/AirdropConfig.tsx
  • components/waves/memes/submission/MemesArtSubmissionContainer.tsx
📚 Learning: 2025-12-30T14:31:53.006Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:53.006Z
Learning: Applies to **/__tests__/**/*.{test,spec}.{ts,tsx,js,jsx}|**/*.{test,spec}.{ts,tsx,js,jsx} : Place tests in `__tests__/` directory or as `ComponentName.test.tsx` files. Mock external dependencies and APIs in tests.

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : Write one behaviour per test with clear, descriptive test names

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
📚 Learning: 2025-12-30T14:32:19.360Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.360Z
Learning: Applies to **/{__tests__,*.test.{tsx,ts}} : Place tests in `__tests__/` directory or as `ComponentName.test.tsx` alongside the component

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/*.{tsx,jsx},!**/__tests__/**,!**/__mocks__/** : Use semantic HTML (`<label>`, `<output>`) over ARIA attributes when possible

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
📚 Learning: 2025-12-30T14:32:19.360Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.360Z
Learning: Applies to **/*.{test,spec}.{tsx,ts} : Mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : All tests must live in `__tests__` directory, mirroring source folder structure (`components`, `contexts`, `hooks`, `utils`)

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use FontAwesome for icons in React components

Applied to files:

  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/*.{tsx,jsx},!**/__tests__/**,!**/__mocks__/** : Every form control must have an associated label element

Applied to files:

  • components/waves/memes/traits/TraitWrapper.tsx
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : Test accessibility with keyboard navigation and screen reader compatibility

Applied to files:

  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : Follow Arrange – Act – Assert pattern in test structure

Applied to files:

  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/*.{ts,tsx,js},!**/__tests__/**,!**/__mocks__/**,!**/*.d.ts : Avoid double negatives in code; prefer explicit statements and use optional chaining (`?.`)

Applied to files:

  • __tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx
🧬 Code graph analysis (8)
components/waves/drop/MemesSingleWaveDropInfoPanel.tsx (3)
helpers/Helpers.ts (1)
  • parseIpfsUrl (290-298)
helpers/file.helpers.ts (1)
  • getFileInfoFromUrl (1-23)
components/download/Download.tsx (1)
  • Download (24-132)
components/utils/input/ens-address/EnsAddressInput.tsx (1)
hooks/useEnsResolution.ts (1)
  • useEnsResolution (13-97)
__tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx (2)
hooks/useEnsResolution.ts (1)
  • useEnsResolution (13-97)
components/utils/input/ens-address/EnsAddressInput.tsx (1)
  • EnsAddressInput (20-80)
components/waves/drop/WaveDropAdditionalInfo.tsx (2)
helpers/Helpers.ts (1)
  • parseIpfsUrl (290-298)
helpers/image.helpers.ts (1)
  • getScaledImageUri (17-45)
components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts (3)
components/waves/memes/submission/types/OperationalData.ts (4)
  • PaymentInfo (21-23)
  • AllowlistBatchRaw (30-34)
  • AdditionalMedia (36-40)
  • AIRDROP_TOTAL (19-19)
__tests__/services/websocket/useWebSocketHealth.test.ts (1)
  • dispatch (45-57)
entities/IProfile.ts (1)
  • CicStatement (58-67)
components/waves/memes/submission/components/PaymentConfig.tsx (4)
components/waves/memes/submission/types/OperationalData.ts (1)
  • PaymentInfo (21-23)
components/waves/memes/submission/utils/addressValidation.ts (1)
  • validateStrictAddress (8-19)
components/waves/memes/traits/TraitWrapper.tsx (1)
  • TraitWrapper (16-98)
components/utils/input/ens-address/EnsAddressInput.tsx (1)
  • EnsAddressInput (20-80)
components/waves/memes/submission/components/AdditionalMediaUpload.tsx (2)
components/waves/memes/submission/hooks/useMediaUpload.ts (1)
  • useMediaUpload (28-136)
components/waves/memes/traits/TraitWrapper.tsx (1)
  • TraitWrapper (16-98)
components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts (1)
components/waves/memes/submission/utils/addressValidation.ts (1)
  • validateStrictAddress (8-19)
🪛 Biome (2.1.2)
__tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx

[error] 67-67: This property is later overwritten by an object member with the same name.

Overwritten with this property.

If an object property with the same name is defined multiple times (except when combining a getter with a setter), only the last definition makes it into the object and previous definitions are ignored.
Unsafe fix: Remove this property.

(lint/suspicious/noDuplicateObjectKeys)

⏰ 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 (35)
components/waves/memes/submission/components/AllowlistBatchManager.tsx (1)

51-51: LGTM on the styling and UX changes.

The increased vertical spacing (gap-y-6), required field indicator on Contract Address, and padding overrides (tw-pb-0) align well with the broader styling strategy updates mentioned in the PR.

Also applies to: 61-61, 65-65, 90-90

components/waves/memes/submission/types/OperationalData.ts (1)

7-7: LGTM!

The new ABOUT_ARTIST enum member, preview_image field in AdditionalMedia, and about_artist field in OperationalData are well-structured and consistent with existing patterns. The enum value will automatically be included in MEMES_SUBMISSION_ADDITIONAL_INFO_KEYS.

Also applies to: 39-39, 48-48

components/waves/memes/traits/TraitWrapper.tsx (2)

55-59: Padding override detection works but relies on class name heuristics.

The includes("tw-pb-") check is a reasonable approach for detecting explicit bottom padding overrides. Be aware this could match unintended patterns if a class name contains tw-pb- as a substring (though unlikely with Tailwind conventions).


89-95: LGTM!

The conditional ValidationError placement correctly handles both scenarios: inline with reduced margin when padding is overridden, and absolutely positioned at the bottom otherwise.

__tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx (1)

1-28: LGTM!

The mock setup is well-structured. The Form.Control mock correctly passes through props for testing, and the useEnsResolution mock provides controllable return values. The import after jest.mock is intentional for proper Jest hoisting.

components/utils/input/ens-address/EnsAddressDisplay.tsx (1)

11-42: LGTM!

The component correctly handles ENS resolution states: loading (with pulse animation), resolved (ENS name + address), and fallback (raw address). The address validation and conditional hook invocation follow wagmi best practices.

components/delegation/walletChecker/WalletChecker.tsx (2)

446-458: LGTM!

The integration of EnsAddressInput is clean. The callbacks properly wire up address resolution (onAddressChange), loading state (onLoadingChange), and error handling (onError). The disabled prop correctly prevents input after data is loaded.


386-388: LGTM!

The early return during ENS loading prevents premature validation errors, and ensLoading is correctly included in the effect's dependency array.

Also applies to: 410-410

components/waves/drop/SingleWaveDropTechnicalDetails.tsx (2)

226-229: LGTM! Payment address now displays ENS names when available.

The integration of EnsAddressDisplay for payment addresses provides a better UX by showing resolved ENS names alongside raw addresses.


256-258: LGTM! Airdrop entries now display ENS-resolved addresses.

Consistent use of EnsAddressDisplay for airdrop wallet addresses.

components/waves/memes/submission/components/AirdropConfig.tsx (3)

20-25: LGTM! Good state management pattern for per-entry loading and error states.

Using Record<string, boolean> maps keyed by entry ID is a clean approach for tracking per-entry states without complex nested structures.


52-74: Good cleanup of per-entry state on removal.

Properly removing the entry's loading and error states prevents memory leaks and stale state issues.


175-186: Verify: Input value displays resolved address, not user's ENS input.

When a user types an ENS name (e.g., vitalik.eth), onAddressChange updates entry.address to the resolved 0x... address. Since value={entry.address}, the input will show the resolved address rather than preserving the ENS name the user typed.

This may be intentional for clarity (showing what will be stored), but differs from the EnsAddressDisplay pattern where both ENS name and address are shown.

__tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx (3)

28-29: LGTM! Test data includes the new about_artist field.

Good coverage for the new metadata field.


57-58: LGTM! Assertion validates ABOUT_ARTIST metadata key presence.


79-80: LGTM! Validates ABOUT_ARTIST is absent when operationalData is not provided.

components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts (2)

377-384: LGTM! Clean reducer case for SET_ABOUT_ARTIST.

Follows the established pattern for operational data updates.


608-620: LGTM! Good UX - auto-populates payment and airdrop addresses from connected wallet.

Pre-filling the user's primary wallet as the default payment and airdrop address reduces friction.

__tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx (1)

61-64: LGTM! Test data updated with new fields.

Properly reflects the expanded operationalData structure.

components/waves/memes/submission/components/PaymentConfig.tsx (1)

41-65: LGTM!

The component structure is clean with proper use of FormSection, TraitWrapper, and EnsAddressInput. Error handling covers both ENS resolution failures and invalid address formats. The conditional ring styling based on error state provides good visual feedback.

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

76-96: LGTM!

The previewImageData derivation handles edge cases well: checks for missing metadata entry, catches JSON parse errors, validates the parsed structure, and ensures file info extraction succeeds before returning data. The null-safe approach prevents runtime errors.


209-248: LGTM!

The conditional rendering logic correctly displays either the main artwork media or the preview image (or both), with appropriate labels and download functionality for each. The grid layout cleanly organizes the media type and download options.

__tests__/components/waves/memes/submission/components/AdditionalMediaUpload.test.tsx (2)

5-17: LGTM!

The defaultProps correctly reflect the updated component API with the new fields (supportingMedia, aboutArtist, previewImage, requiresPreviewImage, previewRequiredMediaType) and their corresponding change handlers. The default values are appropriate for testing.


27-38: Good coverage of conditional rendering.

The tests properly verify that the Preview Image section appears only when requiresPreviewImage is true with the appropriate media type, and is hidden otherwise. This covers the key conditional logic.

components/waves/drop/WaveDropAdditionalInfo.tsx (3)

17-21: LGTM!

The emptyAdditionalMedia constant is correctly extended with the new preview_image field, maintaining consistency with the AdditionalMedia type.


64-109: Clean metadata extraction pattern.

The useMemo consolidates all metadata parsing into a single computation, extracting commentary, aboutArtist, previewImage, and mediaItems efficiently. The helper function getMetadataValue reduces repetition, and the null-safe chaining throughout prevents runtime errors.


122-208: LGTM!

The rendering structure is well-organized with clear section separation. The use of Next.js <Image> components with appropriate sizes props, proper aspect ratio containers, and conditional rendering based on hasContent follows best practices.

components/waves/memes/submission/MemesArtSubmissionContainer.tsx (1)

204-228: LGTM!

The prop wiring for AdditionalInfoStep is correctly aligned with the new form state and handlers.

components/waves/memes/submission/steps/AdditionalInfoStep.tsx (4)

21-41: LGTM!

Interface is well-defined with all props marked readonly per coding guidelines.


76-141: Validation logic is comprehensive and correct.

The isFormValid() function properly validates all required fields including the new payment address, about artist, and conditional preview image requirements.


161-164: LGTM!

Good addition of the PaymentConfig component with proper prop bindings.


179-190: LGTM!

Props are correctly wired to AdditionalMediaUpload with the renamed supportingMedia and new handlers.

components/waves/memes/submission/components/AdditionalMediaUpload.tsx (3)

185-231: LGTM!

The renderMediaSection helper is well-structured with configurable maxItems, acceptTypes, and optional description. The conditional button text and multiple attribute handling are correct.


236-248: LGTM!

The conditional preview image section correctly renders only when requiresPreviewImage is true, with clear helper text explaining why it's needed.


261-295: LGTM!

The new "About the Artist" field is properly integrated using TraitWrapper with consistent styling and error handling alongside the existing "Artwork Commentary" field.

Comment thread __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx Outdated
Comment thread __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx Outdated
Comment thread components/utils/input/ens-address/EnsAddressInput.tsx Outdated
Comment thread components/utils/input/ens-address/EnsAddressInput.tsx Outdated
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts (1)

394-406: Incorrect use of nullish coalescing (??) for boolean OR logic.

isPending and isError are boolean values (not nullable). The ?? operator only continues to the next operand if the left side is null or undefined. When uploadMutation.isPending is false, ?? returns false without checking isSigningDrop or submissionMutation.isPending.

This means isSubmitting will incorrectly be false when only signing or processing is in progress.

🐛 Proposed fix
   return {
     submitArtwork,
     isSubmitting:
-      uploadMutation.isPending ?? isSigningDrop ?? submissionMutation.isPending,
+      uploadMutation.isPending || isSigningDrop || submissionMutation.isPending,
     isUploading: uploadMutation.isPending,
     isSigning: isSigningDrop,
     isProcessing: submissionMutation.isPending,
     uploadProgress,
     submissionPhase,
     submissionError,
     isSuccess: submissionMutation.isSuccess,
-    isError: uploadMutation.isError ?? submissionMutation.isError,
+    isError: uploadMutation.isError || submissionMutation.isError,
     error: uploadMutation.error ?? submissionMutation.error,
🧹 Nitpick comments (3)
components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts (3)

73-86: Potential undefined values in metadata entries.

If operationalData.commentary, operationalData.about_artist, or operationalData.payment_info is undefined, the corresponding data_value will be undefined (note: JSON.stringify(undefined) returns undefined, not a string). This violates the ApiDropMetadata type contract where data_value should be a string.

Consider filtering out entries with undefined/empty values or providing defaults:

♻️ Suggested fix
     const operationalMetadata: ApiDropMetadata[] = [
-      {
-        data_key: "payment_info",
-        data_value: JSON.stringify(operationalData.payment_info),
-      },
-      {
-        data_key: "commentary",
-        data_value: operationalData.commentary,
-      },
-      {
-        data_key: "about_artist",
-        data_value: operationalData.about_artist,
-      },
-    ];
+      operationalData.payment_info && {
+        data_key: "payment_info",
+        data_value: JSON.stringify(operationalData.payment_info),
+      },
+      operationalData.commentary && {
+        data_key: "commentary",
+        data_value: operationalData.commentary,
+      },
+      operationalData.about_artist && {
+        data_key: "about_artist",
+        data_value: operationalData.about_artist,
+      },
+    ].filter((entry): entry is ApiDropMetadata => Boolean(entry));

160-165: Redundant | undefined in type annotation.

The type has | undefined | undefined which is redundant.

♻️ Suggested fix
 interface PhaseChangeCallbacks {
   onPhaseChange?:
-    | ((phase: SubmissionPhase, error?: string) => void)
-    | undefined
-    | undefined;
+    | ((phase: SubmissionPhase, error?: string) => void)
+    | undefined;
 }

284-291: Same redundant | undefined as above.

♻️ Suggested fix
       onPhaseChange?:
-        | ((phase: SubmissionPhase, error?: string) => void)
-        | undefined
-        | undefined;
+        | ((phase: SubmissionPhase, error?: string) => void)
+        | undefined;
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d735cb8 and 5110c7e.

📒 Files selected for processing (2)
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

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

**/*.{ts,tsx,js,jsx}: Remove unnecessary Effects. If the Effect's only job is to derive or sync internal state, calculate during render or use useMemo instead.
Use useEffectEvent for non-reactive logic inside Effects to read the latest props/state without turning them into dependencies or causing unnecessary re-runs.
Use explicit caching with "use cache" directive at the top of Server Components, routes, or functions. Configure cacheComponents: true in next.config.ts as needed.

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{ts,js}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
🧬 Code graph analysis (1)
components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts (2)
generated/models/ApiDropMetadata.ts (1)
  • ApiDropMetadata (16-44)
components/waves/memes/submission/utils/addressValidation.ts (1)
  • validateStrictAddress (8-19)
⏰ 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)

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

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
__tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx (2)

4-5: Unused module-level variables.

mockOnAddressChange and mockValue are assigned inside the mock but never referenced in any test. Remove them to avoid confusion.

🧹 Suggested cleanup
-let mockOnAddressChange: ((address: string) => void) | undefined;
-let mockValue: string | undefined;
-
 jest.mock(
   "@/components/utils/input/ens-address/EnsAddressInput",
   () =>
     function MockEnsAddressInput(props: {
       value?: string;
       placeholder?: string;
       onAddressChange: (address: string) => void;
       className?: string;
     }) {
-      mockOnAddressChange = props.onAddressChange;
-      mockValue = props.value;
       return (
         <input
           data-testid="ens-address-input"
           placeholder={props.placeholder}
           value={props.value ?? ""}
           onChange={(e) => props.onAddressChange(e.target.value)}
-          className={props.className}
         />
       );
     }
 );

30-34: Consider resetting mocks between tests.

The defaultProps.onPaymentInfoChange mock is shared across tests. While not causing issues currently, adding beforeEach to reset mocks ensures test isolation and prevents flaky tests if assertions on this mock are added later. Based on learnings, tests should follow Arrange-Act-Assert pattern with proper isolation.

🧹 Suggested improvement
 describe("PaymentConfig", () => {
+  const mockOnPaymentInfoChange = jest.fn();
+
   const defaultProps = {
     paymentInfo: { payment_address: "" },
-    onPaymentInfoChange: jest.fn(),
+    onPaymentInfoChange: mockOnPaymentInfoChange,
   };
+
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
__tests__/components/walletChecker.test.tsx (2)

87-108: Unnecessary async keyword.

The test function is declared async but doesn't use await. Since the test doesn't wait for any promises, the async modifier is superfluous.

🔧 Suggested fix
-  it("fetches data for valid address", async () => {
+  it("fetches data for valid address", () => {

112-128: Unnecessary async keyword.

Same as above - no await is used in this test.

🔧 Suggested fix
-  it("clears input after clicking clear", async () => {
+  it("clears input after clicking clear", () => {
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1537a1c and af81033.

📒 Files selected for processing (3)
  • __tests__/components/utils/input/ens-address/EnsAddressInput.test.tsx
  • __tests__/components/walletChecker.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/components/utils/input/ens-address/EnsAddressInput.test.tsx
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

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

**/*.{ts,tsx,js,jsx}: Remove unnecessary Effects. If the Effect's only job is to derive or sync internal state, calculate during render or use useMemo instead.
Use useEffectEvent for non-reactive logic inside Effects to read the latest props/state without turning them into dependencies or causing unnecessary re-runs.
Use explicit caching with "use cache" directive at the top of Server Components, routes, or functions. Configure cacheComponents: true in next.config.ts as needed.

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

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

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

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

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Run npm run test to execute all Jest tests and enforce ≥80% line coverage for files changed since main. Tests must pass and coverage threshold must be met before completing any task.

Enforce ≥ 80% line coverage for files changed since main by running npm run test

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

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

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
**/{__tests__,*.test.{tsx,ts}}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
**/*.{test,spec}.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Mock external dependencies and APIs in tests

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
🧠 Learnings (9)
📚 Learning: 2025-12-30T14:31:53.006Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:53.006Z
Learning: Applies to **/__tests__/**/*.{test,spec}.{ts,tsx,js,jsx}|**/*.{test,spec}.{ts,tsx,js,jsx} : Place tests in `__tests__/` directory or as `ComponentName.test.tsx` files. Mock external dependencies and APIs in tests.

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : Write one behaviour per test with clear, descriptive test names

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
📚 Learning: 2025-12-30T14:32:19.360Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.360Z
Learning: Applies to **/{__tests__,*.test.{tsx,ts}} : Place tests in `__tests__/` directory or as `ComponentName.test.tsx` alongside the component

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/*.{tsx,jsx},!**/__tests__/**,!**/__mocks__/** : Use semantic HTML (`<label>`, `<output>`) over ARIA attributes when possible

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
📚 Learning: 2025-12-30T14:32:19.360Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.360Z
Learning: Applies to **/*.{test,spec}.{tsx,ts} : Mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/walletChecker.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : Follow Arrange – Act – Assert pattern in test structure

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : All tests must live in `__tests__` directory, mirroring source folder structure (`components`, `contexts`, `hooks`, `utils`)

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/__mocks__/**/*.{ts,tsx,js} : Jest automatically picks up mocks from `__mocks__` directory

Applied to files:

  • __tests__/components/walletChecker.test.tsx
📚 Learning: 2025-12-30T14:32:37.305Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.305Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : Use realistic production-like data in tests

Applied to files:

  • __tests__/components/walletChecker.test.tsx
⏰ 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)
__tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx (1)

36-79: LGTM!

The test cases are well-structured with clear, descriptive names and follow the Arrange-Act-Assert pattern. Good coverage of:

  • Label and placeholder rendering
  • Helper text presence
  • Callback invocation on user input
  • Pre-populated value display
__tests__/components/walletChecker.test.tsx (1)

29-52: LGTM! Well-structured mock for the EnsAddressInput component.

The mock correctly simulates the component behavior by:

  • Rendering a standard input with appropriate props pass-through
  • Wiring onChange to the onAddressChange callback
  • Handling optional value with nullish coalescing to prevent React warnings

Based on learnings, this follows the pattern of mocking external dependencies in tests.

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

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (2)
components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts (2)

394-395: Incorrect use of nullish coalescing (??) for boolean composition.

isPending is a boolean (true/false), never null/undefined. The ?? operator only falls through on nullish values, so if uploadMutation.isPending is false, the expression short-circuits and returns false immediately—ignoring isSigningDrop and submissionMutation.isPending.

Use logical OR (||) to correctly indicate "submitting if any phase is pending":

🐛 Proposed fix
-    isSubmitting:
-      uploadMutation.isPending ?? isSigningDrop ?? submissionMutation.isPending,
+    isSubmitting:
+      uploadMutation.isPending || isSigningDrop || submissionMutation.isPending,

403-403: Same nullish coalescing issue for isError.

This has the same problem as isSubmitting—use || to correctly capture errors from either mutation.

🐛 Proposed fix
-    isError: uploadMutation.isError ?? submissionMutation.isError,
+    isError: uploadMutation.isError || submissionMutation.isError,
🧹 Nitpick comments (2)
components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts (2)

73-86: Empty or undefined values for commentary and about_artist bypass filtering.

Unlike trait metadata (filtered on lines 66-69 for non-empty values), commentary and about_artist are unconditionally added to the metadata array. If either is undefined or an empty string, it will be included in the API request payload with a potentially invalid data_value.

Consider applying consistent filtering:

♻️ Suggested approach
     const operationalMetadata: ApiDropMetadata[] = [
       {
         data_key: "payment_info",
         data_value: JSON.stringify(operationalData.payment_info),
       },
-      {
-        data_key: "commentary",
-        data_value: operationalData.commentary,
-      },
-      {
-        data_key: "about_artist",
-        data_value: operationalData.about_artist,
-      },
     ];
+
+    if (operationalData.commentary) {
+      operationalMetadata.push({
+        data_key: "commentary",
+        data_value: operationalData.commentary,
+      });
+    }
+
+    if (operationalData.about_artist) {
+      operationalMetadata.push({
+        data_key: "about_artist",
+        data_value: operationalData.about_artist,
+      });
+    }

104-118: Consider filtering empty allowlist batches.

Unlike airdrop_config which filters out invalid entries, allowlist_batches includes all batches even when token_ids_raw is empty. If empty batches aren't meaningful to the API, consider filtering them similarly.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af81033 and aeb4fe0.

📒 Files selected for processing (1)
  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

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

**/*.{ts,tsx,js,jsx}: Remove unnecessary Effects. If the Effect's only job is to derive or sync internal state, calculate during render or use useMemo instead.
Use useEffectEvent for non-reactive logic inside Effects to read the latest props/state without turning them into dependencies or causing unnecessary re-runs.
Use explicit caching with "use cache" directive at the top of Server Components, routes, or functions. Configure cacheComponents: true in next.config.ts as needed.

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{ts,js}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • components/waves/memes/submission/hooks/useArtworkSubmissionMutation.ts
⏰ 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/memes/submission/hooks/useArtworkSubmissionMutation.ts (2)

1-20: LGTM!

Import reorganization is clean. Named imports from React (useCallback, useState) align with coding guidelines.


50-58: LGTM!

Clean destructuring of input parameters improves readability.

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

@prxt6529 prxt6529 merged commit 87a23c6 into main Jan 13, 2026
8 checks passed
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