Skip to content

Designated payee#1733

Merged
prxt6529 merged 4 commits intomainfrom
designated-payee
Jan 13, 2026
Merged

Designated payee#1733
prxt6529 merged 4 commits intomainfrom
designated-payee

Conversation

@prxt6529
Copy link
Copy Markdown
Collaborator

@prxt6529 prxt6529 commented Jan 13, 2026

Summary by CodeRabbit

  • New Features

    • Added designated payee support—payment info now includes an optional designated payee name and toggle; designated payee name is shown where applicable.
    • Drops can include a dedicated preview image, shown across gallery and leaderboard views.
  • UI Improvements

    • Artwork submission rebuilt into a responsive two-column layout for improved browsing and editing.
  • Tests

    • Expanded tests covering designated payee flows and preview-image behavior.

✏️ 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 13, 2026

📝 Walkthrough

Walkthrough

Adds designated-payee fields and UI to meme submission flows, introduces preview-image extraction and consumption for drops, refactors artwork submission layout to a two-column design, and updates related tests and helpers; includes several public-type and component-prop adjustments.

Changes

Cohort / File(s) Summary
Submission types & hook
components/waves/memes/submission/types/OperationalData.ts, components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
Adds has_designated_payee: boolean and designated_payee_name: string to PaymentInfo and initializes them in the submission hook (public data shape expanded).
Payment UI & validation
components/waves/memes/submission/components/PaymentConfig.tsx
Adds Designated Payee checkbox and name input, address validation refinements (addressError / isAddressValid), and updates handlers to emit the extended paymentInfo shape.
Submission layout & step
components/waves/memes/submission/steps/ArtworkStep.tsx
Reworks ArtworkStep to responsive two-column layout with independent scroll containers; adds optional onCancel prop and internal validation/submit helpers.
Technical payment parsing & UI
components/waves/drop/SingleWaveDropTechnicalDetails.tsx
Replaces parsePaymentAddress with parsePaymentDetails returning { address, designatedPayeeName }; updates UI to display designated payee name and use parsed address.
Preview image extraction helper
helpers/waves/drop.helpers.ts, __tests__/helpers/waves/drop.helpers.test.ts
Adds getDropPreviewImageUrl(metadata) (exported) to parse preview_image from metadata safely; adjusts Drop types/DropSize enum and tests covering parsing, missing data, and IPFS handling.
Media display & consumption
components/drops/view/item/content/media/MediaDisplay.tsx, components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx, components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx, __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
MediaDisplay gains optional previewImageUrl prop and short-circuits non-image media rendering to show a preview; gallery/leaderboard components compute previewImageUrl with getDropPreviewImageUrl and prefer it when rendering; added tests for preview rendering.
Memes drop info panel
components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
Adds `wave: ApiWave
Single leaderboards & tests
__tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx, __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx, __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
Tests expanded to include designated payee fields in fixtures; PaymentConfig tests add coverage for checkbox, visibility, value changes, and callbacks; mutation tests expect new fields serialized.
Misc — package.json
package.json
test-json-changed script changed to append --coverage=false.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • simo6529
  • ragnep

Poem

🐰 I hopped in with a tiny cheer,
Payees named now, and previews near.
Two columns wide, the flows delight,
Media shines and forms feel light.
Hooray — a rabbit’s patch of code so bright! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% 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 'Designated payee' accurately summarizes the main change across the changeset, which introduces designated payee functionality including new UI components, payment configuration fields, and helper functions.

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

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6ed994 and 9860f08.

📒 Files selected for processing (1)
  • components/waves/memes/submission/components/PaymentConfig.tsx
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{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/PaymentConfig.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

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

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

Files:

  • components/waves/memes/submission/components/PaymentConfig.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/PaymentConfig.tsx
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

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

Files:

  • components/waves/memes/submission/components/PaymentConfig.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/PaymentConfig.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • components/waves/memes/submission/components/PaymentConfig.tsx
🧬 Code graph analysis (1)
components/waves/memes/submission/components/PaymentConfig.tsx (1)
components/waves/memes/traits/TraitWrapper.tsx (1)
  • TraitWrapper (16-98)
🔇 Additional comments (7)
components/waves/memes/submission/components/PaymentConfig.tsx (7)

1-13: LGTM!

Imports are well-organized and the interface correctly uses readonly for props as per coding guidelines.


15-28: LGTM!

State variables and address validation logic are correctly implemented. The getAddressError function appropriately prioritizes ENS errors and handles empty addresses gracefully.


30-59: LGTM!

All callback handlers are correctly memoized with proper dependency arrays. The toggle handler appropriately clears the designated payee name when unchecked.


61-70: LGTM!

Computed values are correctly derived during render per coding guidelines. The validation logic properly uses trim() to check for meaningful content.


72-94: LGTM!

The checkbox implementation includes proper accessibility attributes (aria-label) and clear descriptive text explaining the designated payee feature.


117-138: LGTM!

The payment address input correctly adapts its label based on the designated payee state. The error handling and validation states are properly integrated with TraitWrapper and EnsAddressInput components.


110-112: No action needed. The class tw-ring-red is valid and correctly defined in the Tailwind configuration at the project root. The config explicitly defines red: "#F97066" as a custom color, and with the tw- prefix setting, this generates the tw-ring-red utility automatically. The consistent usage across multiple components confirms this is intentional design, not a styling issue.

Likely an incorrect or invalid review comment.


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: 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/useArtworkSubmissionForm.ts (1)

612-616: Partial update may reset designated payee fields.

When connectedProfile.primary_wallet changes, SET_PAYMENT_INFO dispatches only { payment_address: primaryWallet }. The reducer at line 338-345 replaces the entire payment_info object, which will reset has_designated_payee and designated_payee_name to undefined.

Consider spreading the existing payment_info to preserve the designated payee fields:

Proposed fix
     if (primaryWallet) {
       dispatch({
         type: "SET_PAYMENT_INFO",
-        payload: { payment_address: primaryWallet },
+        payload: { 
+          ...state.operationalData.payment_info,
+          payment_address: primaryWallet 
+        },
       });

Note: This requires accessing current state, which may need restructuring the effect or using a different action type for partial updates.

🧹 Nitpick comments (7)
components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx (1)

46-53: Replace <img> with <Image /> from next/image.

Per coding guidelines, use Next.js <Image /> component instead of raw <img> elements to comply with @next/next/no-img-element ESLint rule.

♻️ Suggested fix
+import Image from "next/image";
         {previewImageUrl ? (
           <div className="tw-w-full tw-flex tw-justify-center">
-            <img
+            <Image
               src={getScaledImageUri(previewImageUrl, ImageScale.AUTOx450)}
               alt="Preview"
-              className="tw-max-w-full tw-max-h-48 tw-object-contain tw-rounded-lg"
+              width={450}
+              height={192}
+              className="tw-max-w-full tw-max-h-48 tw-object-contain tw-rounded-lg"
+              unoptimized
             />
           </div>
components/waves/memes/submission/components/PaymentConfig.tsx (1)

103-113: Consider removing autoFocus for better accessibility.

The autoFocus attribute on line 108 may cause unexpected page scrolling and can be disorienting for screen reader users. Consider relying on natural tab flow instead.

components/waves/memes/submission/steps/ArtworkStep.tsx (3)

47-49: Avoid as any type assertion.

The as any cast bypasses type safety. Consider using proper type guards or expanding READ_ONLY_FIELDS type.

♻️ Suggested fix
-const READ_ONLY_FIELDS = ["seizeArtistProfile"] as const;
+const READ_ONLY_FIELDS: ReadonlyArray<keyof TraitsData> = ["seizeArtistProfile"];

Then remove the as any casts:

-      if (READ_ONLY_FIELDS.includes(field as any)) continue;
+      if ((READ_ONLY_FIELDS as readonly string[]).includes(field)) continue;

65-75: Remove redundant null/undefined checks after typeof.

After typeof value === "number", the value cannot be null or undefined (since typeof null === "object" and typeof undefined === "undefined"). Same applies to the boolean check.

♻️ Suggested fix for getSubmitButtonTooltip
       // Number fields
       else if (typeof value === "number") {
-        if (value === null || value === undefined || isNaN(value)) {
+        if (isNaN(value)) {
           return `Please enter ${fieldName}`;
         }
       }
       // Boolean fields need explicit value
       else if (typeof value === "boolean") {
-        if (value === null || value === undefined) {
-          return `Please set ${fieldName}`;
-        }
+        // Boolean is valid if we reach here (typeof already confirmed)
       }

17-31: Consider removing comments per coding guidelines.

Per coding guidelines, code should be self-explanatory without comments. The function names getSubmitButtonTooltip and checkFormCompleteness are already descriptive.

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

283-289: Consider replacing <img> with <Image /> from next/image.

Per coding guidelines, use Next.js <Image /> component. For fullscreen artwork display where optimization may not be desired, use unoptimized prop.

♻️ Suggested 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}
+                fill
+                unoptimized
                 className="tw-max-h-full tw-max-w-full tw-object-contain"
               />
             </div>
helpers/waves/drop.helpers.ts (1)

73-108: Dead code: the closest?.type === DropSize.LIGHT check can never be true.

Since LIGHT drops are skipped at lines 75-77 and closest is initialized to null, the accumulator can only ever be null or a FULL drop. The condition at line 87 is unreachable.

♻️ Suggested simplification
       if (
         current.author.handle === newDrop.author.handle &&
         current.parts.map((p) => p.content).join("") ===
           newDrop.parts.map((p) => p.content).join("") &&
         Math.abs(
           new Date(current.created_at).getTime() -
             new Date(newDrop.created_at).getTime()
         ) < MAX_TIME_DIFFERENCE
       ) {
-        if (closest?.type === DropSize.LIGHT) {
-          return current;
-        }
-
         if (
           !closest ||
           Math.abs(
             new Date(current.created_at).getTime() -
               new Date(newDrop.created_at).getTime()
           ) <
             Math.abs(
               new Date(closest.created_at).getTime() -
                 new Date(newDrop.created_at).getTime()
             )
         ) {
           return current;
         }
       }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e69d0c1 and a6ed994.

📒 Files selected for processing (16)
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • __tests__/helpers/waves/drop.helpers.test.ts
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/steps/ArtworkStep.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • helpers/waves/drop.helpers.ts
  • package.json
🧰 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:

  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • __tests__/helpers/waves/drop.helpers.test.ts
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • helpers/waves/drop.helpers.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/memes/submission/steps/ArtworkStep.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

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

**/*.{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/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/memes/submission/steps/ArtworkStep.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/helpers/waves/drop.helpers.test.ts
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.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/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • __tests__/helpers/waves/drop.helpers.test.ts
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • helpers/waves/drop.helpers.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/memes/submission/steps/ArtworkStep.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/memes/submission/steps/ArtworkStep.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • __tests__/helpers/waves/drop.helpers.test.ts
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • helpers/waves/drop.helpers.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/memes/submission/steps/ArtworkStep.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • __tests__/helpers/waves/drop.helpers.test.ts
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • helpers/waves/drop.helpers.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/memes/submission/steps/ArtworkStep.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/helpers/waves/drop.helpers.test.ts
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
**/*.{test,spec}.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Mock external dependencies and APIs in tests

Files:

  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • __tests__/helpers/waves/drop.helpers.test.ts
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.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/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • __tests__/helpers/waves/drop.helpers.test.ts
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
  • components/waves/memes/submission/components/PaymentConfig.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/memes/submission/types/OperationalData.ts
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • helpers/waves/drop.helpers.ts
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/memes/submission/steps/ArtworkStep.tsx
  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/hooks/useArtworkSubmissionForm.ts
  • __tests__/helpers/waves/drop.helpers.test.ts
  • components/waves/memes/submission/types/OperationalData.ts
  • helpers/waves/drop.helpers.ts
🧠 Learnings (12)
📚 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
  • package.json
  • __tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.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 **/*.{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/waves/small-leaderboard/WaveSmallLeaderboardItemContent.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__/** : Every form control must have an associated label element

Applied to files:

  • __tests__/components/waves/memes/submission/components/PaymentConfig.test.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 **/*.{test,spec}.{js,ts,jsx,tsx} : 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.

Applied to files:

  • package.json
📚 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}.{js,ts,jsx,tsx} : Enforce ≥ 80% line coverage for files changed since `main` by running `npm run test`

Applied to files:

  • package.json
📚 Learning: 2025-12-30T14:32:44.885Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: app/api/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:44.885Z
Learning: Applies to app/api/**/*.{ts,tsx} : All changes to API routes must pass the commands listed in the top-level AGENTS.md: `npm run test` and `npm run lint`.

Applied to files:

  • package.json
📚 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 **/*.{js,ts,jsx,tsx} : Code must satisfy ESLint with Next's Core Web Vitals and React Hooks rules by running `npm run lint`

Applied to files:

  • package.json
📚 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 **/*.{js,ts,jsx,tsx} : Run `npm run lint` to ensure code satisfies ESLint (Next's Core Web Vitals + React Hooks). Code must pass linting before completing any task.

Applied to files:

  • package.json
📚 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/small-leaderboard/WaveSmallLeaderboardItemContent.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 **/*.{tsx,ts,jsx,js} : Prefer direct named imports from React (`useMemo`, `useRef`, `FC`) over `React.` namespace usage

Applied to files:

  • components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.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/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx
🧬 Code graph analysis (8)
__tests__/helpers/waves/drop.helpers.test.ts (1)
helpers/waves/drop.helpers.ts (1)
  • getDropPreviewImageUrl (168-185)
__tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx (1)
components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx (1)
  • WaveSmallLeaderboardItemContent (18-171)
components/waves/drop/SingleWaveDropTechnicalDetails.tsx (1)
components/utils/input/ens-address/EnsAddressDisplay.tsx (1)
  • EnsAddressDisplay (11-42)
components/waves/memes/submission/components/PaymentConfig.tsx (1)
components/waves/memes/traits/TraitWrapper.tsx (1)
  • TraitWrapper (16-98)
components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx (2)
helpers/waves/drop.helpers.ts (1)
  • getDropPreviewImageUrl (168-185)
helpers/image.helpers.ts (1)
  • getScaledImageUri (17-45)
helpers/waves/drop.helpers.ts (2)
generated/models/ApiDropMetadata.ts (1)
  • ApiDropMetadata (16-44)
helpers/Helpers.ts (1)
  • parseIpfsUrl (290-298)
components/waves/drop/MemesSingleWaveDropInfoPanel.tsx (2)
helpers/waves/drop.helpers.ts (1)
  • getDropPreviewImageUrl (168-185)
helpers/file.helpers.ts (1)
  • getFileInfoFromUrl (1-23)
components/waves/leaderboard/gallery/WaveLeaderboardGalleryItem.tsx (1)
helpers/waves/drop.helpers.ts (1)
  • getDropPreviewImageUrl (168-185)
🔇 Additional comments (23)
__tests__/components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.test.tsx (2)

4-4: LGTM!

Import correctly references the enum used to construct metadata keys for the preview image test case.


20-42: LGTM! Good test coverage for preview image behavior.

Both test cases properly verify the branching logic:

  1. When ADDITIONAL_MEDIA metadata contains a preview_image, the component renders an <img> with alt "Preview" and skips the media placeholder.
  2. When no preview image exists, the original media is rendered via the mocked WaveDropPartContentMedias.

The tests align with the component's getDropPreviewImageUrl integration described in the relevant code snippets.

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

21-25: LGTM!

The PaymentInfo interface extension is clean. The boolean toggle + name string pattern properly supports the designated payee UI flow.

package.json (1)

18-18: Verify coverage enforcement alignment.

The test-json-changed script now explicitly disables coverage with --coverage=false. Per coding guidelines, ≥80% line coverage is required for files changed since main.

Confirm this is intentional and that coverage enforcement is handled by a separate CI step or the base test script.

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

419-420: LGTM!

Initial state correctly sets sensible defaults for the new designated payee fields.

components/drops/view/item/content/media/MediaDisplay.tsx (2)

27-43: LGTM!

The documentation clearly explains the preview image behavior, and the prop typing correctly allows for nullable/undefined values from upstream callers.


71-73: LGTM! Clean short-circuit for preview images.

The logic correctly bypasses non-image media rendering when a preview image is available, while preserving normal behavior for actual image media types.

components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx (1)

30-62: LGTM on the preview image logic.

The conditional rendering correctly prioritizes the preview image URL when available and falls back to the existing media rendering. The useMemo dependency is appropriate.

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

37-59: LGTM on the designated payee handlers.

The toggle and name change handlers are properly memoized with useCallback and correct dependency arrays. The toggle appropriately clears the payee name when unchecked.


61-70: LGTM on the derived state and validation logic.

The validation correctly requires the designated payee name when the toggle is enabled, and the address validation combines ENS error state with format validation properly.

components/waves/memes/submission/steps/ArtworkStep.tsx (1)

301-353: LGTM on the two-column responsive layout.

The layout correctly implements independent scrolling for each column with appropriate responsive breakpoints. The scrollbar styling is consistent with the design system.

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

54-58: LGTM on the test data update.

The test data correctly includes the new has_designated_payee and designated_payee_name fields with appropriate default values, aligning with the expanded PaymentInfo type.

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

17-29: LGTM on the test data expansion.

The mock data correctly includes the new designated payee fields and preview image. The existing test at line 54 will verify these fields are serialized in the metadata.

Consider adding a test case that verifies behavior when has_designated_payee: true and designated_payee_name contains a value, to ensure the enabled state is properly serialized.

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

64-89: LGTM on the PaymentDetails parsing implementation.

The new parsePaymentDetails function properly handles JSON parsing with appropriate fallbacks, validates the has_designated_payee flag with strict equality, and safely extracts the designated payee name only when applicable.


238-265: LGTM on the designated payee UI rendering.

The payment address section correctly displays the designated payee name when available, and the copy functionality properly copies the address. The inline display with the label is a clean UX choice.

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

77-85: LGTM on the preview image data extraction.

The useMemo correctly uses the shared getDropPreviewImageUrl helper and derives file info from the URL. The null checks ensure safe rendering.


87-96: LGTM on the fileName composition.

The useMemo correctly incorporates the wave name and author handle into the filename with proper null checks using optional chaining.

__tests__/helpers/waves/drop.helpers.test.ts (1)

35-74: LGTM!

The test suite comprehensively covers all edge cases for getDropPreviewImageUrl: undefined/empty metadata, missing entries, invalid JSON, and valid IPFS URL parsing. Good use of the MemesSubmissionAdditionalInfoKey.ADDITIONAL_MEDIA constant for consistency with the implementation.

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

48-51: LGTM!

Good use of useMemo to cache the preview image URL computation, which involves JSON parsing. The dependency on drop.metadata is correct.

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

35-37: Good addition of beforeEach to clear mocks.

This ensures test isolation and prevents mock state from leaking between tests.


52-126: LGTM!

Comprehensive test coverage for the designated payee feature:

  • Checkbox rendering and default state
  • Conditional visibility of the name field
  • State changes on user interactions
  • Proper verification of callback invocations with full expected payloads

170-191: LGTM!

Good test for the clearing behavior when unchecking the designated payee checkbox—verifies that designated_payee_name is reset to an empty string.

helpers/waves/drop.helpers.ts (1)

168-185: LGTM!

Well-implemented utility with proper defensive coding:

  • Handles undefined/empty metadata
  • Graceful error handling for JSON parse failures
  • Checks for missing preview_image before URL transformation
  • Clean integration with existing parseIpfsUrl helper

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

@prxt6529 prxt6529 merged commit 204a2e5 into main Jan 13, 2026
4 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jan 29, 2026
This was referenced Apr 21, 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