Skip to content

Submission additional fields#1690

Merged
simo6529 merged 50 commits intomainfrom
submission-additional-fields
Jan 6, 2026
Merged

Submission additional fields#1690
simo6529 merged 50 commits intomainfrom
submission-additional-fields

Conversation

@simo6529
Copy link
Copy Markdown
Collaborator

@simo6529 simo6529 commented Jan 2, 2026

Summary by CodeRabbit

  • New Features

    • Added an "Additional Information" submission step: airdrop config, payment & allowlist entries, supplemental media uploads (max 4 per section), and artwork commentary; drops now display additional info and technical/metadata details.
  • UX

    • Artwork step primary button now reads "Continue"; added back/cancel navigation handlers and streamlined submission flow.
  • Validation

    • Strict Ethereum address validation and robust token ID format checks.
  • Tests

    • Expanded unit test coverage across new UI, hooks, and utilities.
  • Documentation

    • Added product, tech-stack, workflow, and style guideline docs.

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

Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@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 (3)
components/waves/drop/WaveDropAdditionalInfo.tsx (2)

76-76: Redundant type guard in filter predicate.

Line 76 filters artwork_commentary_media (which is already string[]) with a type predicate (url): url is string => typeof url === "string". Since the array is already typed as string[], this guard is unnecessary. The filter should only check for truthy values.

🔎 Simplify the type guard
-      .filter((url): url is string => typeof url === "string")
+      .filter((url): url is string => Boolean(url))

111-111: Potential key collision with duplicate URLs.

If the same URL appears multiple times in artwork_commentary_media, the key ${item.url}-${index} could lead to confusion since React keys should be unique per item. While the index makes it unique, consider whether duplicate URLs are valid in your use case.

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

13-64: Consider expanding test coverage.

The current tests cover essential functionality:

  • Null rendering when no data exists
  • Commentary rendering
  • Media limit enforcement (4 items max)

However, consider adding tests for:

  • Combined commentary and media rendering
  • Video media (to verify <video> element rendering)
  • IPFS URL transformation
  • Invalid JSON handling in additional_media
  • Empty media arrays
Example test for combined commentary + media
it("renders both commentary and media together", () => {
  const additionalMedia = JSON.stringify({
    artist_profile_media: [],
    artwork_commentary_media: ["https://example.com/1.jpg"],
  });

  render(
    <WaveDropAdditionalInfo
      drop={buildDrop([
        {
          data_key: MemesSubmissionAdditionalInfoKey.COMMENTARY,
          data_value: "Process notes here.",
        },
        {
          data_key: MemesSubmissionAdditionalInfoKey.ADDITIONAL_MEDIA,
          data_value: additionalMedia,
        },
      ])}
    />
  );

  expect(screen.getByText("Process notes here.")).toBeInTheDocument();
  expect(screen.getByRole("img")).toBeInTheDocument();
});
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a1de33f and 6b62be4.

📒 Files selected for processing (4)
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.test.tsx
  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • components/waves/drop/WaveDropAdditionalInfo.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:

  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.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:

  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.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/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.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:

  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.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/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.test.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.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:

  • components/waves/drop/MemesSingleWaveDropInfoPanel.tsx
  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
  • components/waves/drop/WaveDropAdditionalInfo.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.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/drop/WaveDropAdditionalInfo.test.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.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/drop/WaveDropAdditionalInfo.test.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.test.tsx
**/*.{test,spec}.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Mock external dependencies and APIs in tests

Files:

  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.test.tsx
🧠 Learnings (9)
📚 Learning: 2025-12-30T14:31:52.993Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:52.993Z
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/drop/WaveDropAdditionalInfo.test.tsx
  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.test.tsx
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : Use realistic production-like data in tests

Applied to files:

  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
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/drop/WaveDropAdditionalInfo.test.tsx
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
Learning: Applies to __tests__/**/__tests__/**/*.{ts,tsx,js} : Write one behaviour per test with clear, descriptive test names

Applied to files:

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

Applied to files:

  • __tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx
📚 Learning: 2025-12-30T14:32:19.339Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.339Z
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/drop/WaveDropAdditionalInfo.test.tsx
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
Learning: Applies to __tests__/**/*.{ts,tsx,js},!**/__tests__/**,!**/__mocks__/**,!**/*.d.ts : Use `Element.remove()` method instead of `parentNode.removeChild(element)`

Applied to files:

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

Applied to files:

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

Applied to files:

  • __tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.test.tsx
🧬 Code graph analysis (3)
components/waves/drop/MemesSingleWaveDropInfoPanel.tsx (2)
hooks/drops/useDropInteractionRules.ts (1)
  • useDropInteractionRules (26-140)
components/waves/drop/WaveDropAdditionalInfo.tsx (1)
  • WaveDropAdditionalInfo (58-136)
__tests__/components/waves/drop/WaveDropAdditionalInfo.test.tsx (1)
components/waves/drop/WaveDropAdditionalInfo.tsx (1)
  • WaveDropAdditionalInfo (58-136)
components/waves/drop/WaveDropAdditionalInfo.tsx (6)
components/waves/memes/submission/types/OperationalData.ts (1)
  • AdditionalMedia (33-36)
helpers/video.helpers.ts (1)
  • isVideoUrl (68-81)
helpers/file.helpers.ts (1)
  • getFileInfoFromUrl (1-23)
helpers/waves/drop.helpers.ts (1)
  • ExtendedDrop (16-20)
helpers/Helpers.ts (1)
  • parseIpfsUrl (287-295)
helpers/image.helpers.ts (1)
  • getScaledImageUri (17-45)
⏰ 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 (8)
components/waves/drop/WaveDropAdditionalInfo.tsx (2)

122-128: LGTM: Proper Next.js Image usage with responsive sizing.

The Next.js Image component is correctly configured with fill, appropriate sizes for responsive layouts, and tw-object-contain for proper aspect ratio handling. The alt text is descriptive.


22-44: Robust JSON parsing with proper error handling.

The parseAdditionalMedia function properly handles:

  • Missing/falsy input
  • JSON parse errors with try-catch
  • Type validation of parsed result
  • Array validation with Array.isArray()
  • Filtering of falsy values with .filter(Boolean)
__tests__/components/waves/drop/MemesSingleWaveDropInfoPanel.test.tsx (2)

16-16: LGTM: Consistent mock pattern.

The mock for WaveDropAdditionalInfo follows the same pattern as other component mocks in the test suite, returning a simple div with a data-testid for verification.


34-34: LGTM: Test coverage for new component.

The test correctly verifies that the new WaveDropAdditionalInfo component is rendered within the panel.

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

5-8: LGTM: Proper Next.js Image mocking.

The mock for next/image correctly replaces the Image component with a standard img element for testing purposes, following Jest mocking conventions.

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

15-15: LGTM: Clean import addition.

The import for WaveDropAdditionalInfo follows the existing pattern and is correctly placed with other local component imports.


209-209: LGTM: Logical component placement.

The WaveDropAdditionalInfo component is rendered in a semantically appropriate location within the info panel, positioned after the core drop details and before the media type/download section. The component receives the required drop prop correctly.


67-68: Minor: Formatting change to destructuring.

The destructuring assignment was split across two lines, likely for line length or readability. This is purely a formatting change with no functional impact.

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

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
components/waves/drop/SingleWaveDropTechnicalDetails.tsx (1)

207-207: Minor styling inconsistency in container borders.

The border colors vary across sections:

  • Payment Address: tw-border-iron-800 (line 207)
  • Airdrop: tw-border-iron-900 (line 229)
  • Allowlist: tw-border-iron-900 but missing tw-rounded-lg (line 265)

If this is intentional visual hierarchy, consider it verified. Otherwise, standardize for consistency.

Also applies to: 229-229, 265-265

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b62be4 and 4ae2670.

📒 Files selected for processing (2)
  • components/waves/drop/SingleWaveDropInfoDetails.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.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/drop/SingleWaveDropInfoDetails.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.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/drop/SingleWaveDropInfoDetails.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.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/drop/SingleWaveDropInfoDetails.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.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/drop/SingleWaveDropInfoDetails.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.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/drop/SingleWaveDropInfoDetails.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • components/waves/drop/SingleWaveDropInfoDetails.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.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/drop/SingleWaveDropInfoDetails.tsx
  • components/waves/drop/SingleWaveDropTechnicalDetails.tsx
🧬 Code graph analysis (1)
components/waves/drop/SingleWaveDropInfoDetails.tsx (1)
components/waves/drop/SingleWaveDropTechnicalDetails.tsx (1)
  • SingleWaveDropTechnicalDetails (106-335)
⏰ 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 (7)
components/waves/drop/SingleWaveDropInfoDetails.tsx (1)

4-4: LGTM! Clean integration of the technical details component.

The new SingleWaveDropTechnicalDetails component is integrated consistently with the existing patterns in this file.

Also applies to: 18-18

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

1-10: LGTM! Imports follow best practices.

Direct React hook imports and appropriate "use client" directive for this interactive component.


106-167: LGTM! Solid component logic with proper memoization.

The component efficiently parses metadata, handles clipboard API availability, and provides appropriate user feedback via toasts.


234-236: Verify uniqueness of addresses and contracts in lists.

The keys combine the identifier with the index (e.g., ${entry.address}-${index}). This approach works but might mask issues if duplicate addresses or contracts exist in the data. Confirm that:

  • Airdrop addresses are expected to be unique
  • Allowlist contracts are expected to be unique per batch

If duplicates are possible, the current approach is correct. If they're not expected, consider adding validation in the parsing functions to warn about duplicates.

Also applies to: 270-272


22-32: LGTM! Safe JSON parsing with appropriate fallback.

The generic parser correctly handles edge cases with try-catch and null coalescing.


315-332: LGTM! Tooltip configuration is comprehensive.

Fixed positioning and high z-index ensure tooltips render correctly above other UI elements.


84-91: The token ID format handling is correct and defensive.

The code appropriately prioritizes token_ids_raw (line 89–90), which preserves user input formats like "1-5" and "1,3-5,7", before falling back to joining arrays with ", " (line 88) only if the raw format is unavailable. Since the submission layer sends data as token_ids_raw strings and the validation enforces range notation support, the parsing logic correctly maintains the original format for both display and clipboard copying.

Likely an incorrect or invalid review comment.

Comment thread components/waves/drop/SingleWaveDropTechnicalDetails.tsx
simo6529 and others added 7 commits January 5, 2026 07:40
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Fix all issues with AI Agents 🤖
In @components/waves/memes/submission/hooks/useMediaUpload.ts:
- Around line 73-85: When handling the upload error in the catch block where
URL.revokeObjectURL(item.previewUrl) is called, also clear the revoked preview
URL in the state update so UI won't try to render a broken image; update the
setItems mapping for the matching item (the i.id === item.id branch) to include
previewUrl: undefined (or null) along with status: "error" and error: errorMsg
so the stored item no longer contains the revoked URL.
- Around line 28-118: The hook useMediaUpload creates blob preview URLs (created
in the addFiles flow) but never revokes them on unmount; add a useEffect in
useMediaUpload that runs a cleanup function on unmount to iterate over current
items and call URL.revokeObjectURL for each item.previewUrl, and optionally
maintain a Ref (e.g., previewUrlsRef) to track created preview URLs to avoid
stale dependency issues so the cleanup doesn't need items in its dependency
array; ensure removeItem still revokes individual URLs as it currently does.
🧹 Nitpick comments (3)
components/waves/memes/submission/hooks/useMediaUpload.ts (3)

40-49: Consider crypto.randomUUID() for ID generation.

The current ID generation using Date.now() and Math.random() works, but crypto.randomUUID() provides better uniqueness and is more standard.

🔎 Optional refactor
-        id: `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,
+        id: crypto.randomUUID(),

52-86: Consider parallel uploads for better performance.

Uploads are processed sequentially (one file at a time). For multiple files, parallel uploads with a concurrency limit (e.g., using Promise.all or a concurrency helper) would improve performance.

However, the current sequential approach may be intentional for simpler progress tracking and to avoid overwhelming the server with multiple upload initializations.

🔎 Example parallel upload with concurrency limit

You could use a library like p-limit to control concurrency:

import pLimit from 'p-limit';

const limit = pLimit(2); // Upload 2 files concurrently

const uploadPromises = newItems.map((item) =>
  limit(async () => {
    try {
      const result = await multiPartUpload({
        file: item.file,
        path: "drop",
        onProgress: (progress) => {
          setItems((prev) =>
            prev.map((i) =>
              i.id === item.id ? { ...i, progress } : i
            )
          );
        },
      });
      setItems((prev) =>
        prev.map((i) =>
          i.id === item.id
            ? { ...i, serverUrl: result.url, status: "done" as const, progress: 100 }
            : i
        )
      );
    } catch (error) {
      // ... error handling
    }
  })
);

await Promise.all(uploadPromises);

107-108: Consider memoizing derived state.

isUploading and hasErrors are recomputed on every render. For better performance, especially if these values are passed to child components or used in effect dependencies, consider memoizing them with useMemo.

🔎 Proposed refactor
+import { useState, useCallback, useMemo } from "react";

-  const isUploading = items.some((i) => i.status === "uploading");
-  const hasErrors = items.some((i) => i.status === "error");
+  const isUploading = useMemo(
+    () => items.some((i) => i.status === "uploading"),
+    [items]
+  );
+  const hasErrors = useMemo(
+    () => items.some((i) => i.status === "error"),
+    [items]
+  );
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4df1f33 and 7e6aa22.

📒 Files selected for processing (1)
  • components/waves/memes/submission/hooks/useMediaUpload.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/useMediaUpload.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/useMediaUpload.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/useMediaUpload.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • components/waves/memes/submission/hooks/useMediaUpload.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/useMediaUpload.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/useMediaUpload.ts
🧠 Learnings (2)
📚 Learning: 2025-12-30T14:31:52.993Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:52.993Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript with React functional components and hooks. Follow existing code style and naming conventions.

Applied to files:

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

Applied to files:

  • components/waves/memes/submission/hooks/useMediaUpload.ts
🧬 Code graph analysis (1)
components/waves/memes/submission/hooks/useMediaUpload.ts (1)
components/waves/create-wave/services/multiPartUpload.ts (1)
  • multiPartUpload (48-244)
⏰ 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 (4)
components/waves/memes/submission/hooks/useMediaUpload.ts (4)

1-4: LGTM!

Imports are correct and follow the coding guidelines for direct named imports from React.


6-23: LGTM!

Interface definitions are clear and correctly typed.


29-29: LGTM!

State initialization is correct.


34-37: LGTM!

Slot limiting logic correctly enforces the maxFiles constraint.

Comment thread components/waves/memes/submission/hooks/useMediaUpload.ts
Comment thread components/waves/memes/submission/hooks/useMediaUpload.ts
prxt6529 and others added 5 commits January 6, 2026 09:03
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 (1)
.gitignore (1)

100-100: Clarify purpose and add trailing slash for directory entries.

The new .hooks entry is added without context. Assuming it's a directory (like the existing .githooks/ on line 93), consider:

  1. Add trailing slash for consistency: Use .hooks/ to explicitly indicate a directory, matching the format of .githooks/ on line 93.
  2. Clarify purpose: What does .hooks contain? How does it differ from the existing .githooks/? A brief comment above the entry would help future maintainers.
🔎 Suggested improvement
# generated env schema for Node runtime
/config/env.schema.runtime.cjs
.githooks/
scripts/lint-to-json.js

# Sentry Config File
.env.sentry-build-plugin
eslint-rule-summary.csv
~
+# Local development hooks and build artifacts
-.hooks
+.hooks/
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e6aa22 and 72e704c.

📒 Files selected for processing (1)
  • .gitignore
⏰ 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: Simo <simo@6529.io>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Jan 6, 2026

Quality Gate Passed Quality Gate passed

Issues
0 New issues
3 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.1% Duplication on New Code

See analysis details on SonarQube Cloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (7)
scripts/wt-add.sh (2)

46-57: Consider moving hook setup after npm install or adding dependency checks.

The pre-commit hook is configured before npm dependencies are installed. If this script is interrupted or fails between the hook setup and npm install completion, the worktree will have a pre-commit hook that references npm run lint:uncommitted:tight but won't have the necessary dependencies installed. This could cause confusing errors on the first commit attempt.

Consider either:

  • Moving this section after the npm install step (lines 59-60)
  • Adding a check in the hook to verify npm and dependencies are available before running lint
🔎 Proposed fix: Add dependency check to pre-commit hook
 cat > "../$WORKTREE_NAME/.hooks/pre-commit" <<'HOOK'
 #!/bin/sh
+set -e
+if [ ! -d "node_modules" ]; then
+  echo "⚠️  Warning: node_modules not found. Run 'npm install' first."
+  exit 1
+fi
 npm run lint:uncommitted:tight
 HOOK

Alternatively, move the entire hook setup section after line 60 (after npm install).


49-52: Consider adding error handling to the pre-commit hook.

The hook script runs without explicit error handling. Adding set -e would ensure the hook fails fast if the npm command encounters issues, making the behavior more predictable.

🔎 Proposed enhancement
 cat > "../$WORKTREE_NAME/.hooks/pre-commit" <<'HOOK'
 #!/bin/sh
+set -e
 npm run lint:uncommitted:tight
 HOOK
__tests__/components/waves/memes/submission/components/AllowlistBatchManager.test.tsx (2)

6-19: Consider testing the exact shape of newly added batches.

Line 17 uses expect.objectContaining which doesn't verify that the generated batch has an id field (which is expected based on lines 23-24 and other tests). Consider asserting the complete structure including the presence of the id field to ensure consistent batch creation.

🔎 Suggested enhancement
-    expect(onBatchesChange).toHaveBeenCalledWith([
-      expect.objectContaining({ contract: "", token_ids_raw: "" }),
-    ]);
+    expect(onBatchesChange).toHaveBeenCalledWith([
+      expect.objectContaining({ 
+        id: expect.any(String),
+        contract: "", 
+        token_ids_raw: "" 
+      }),
+    ]);

5-61: Consider adding tests for validation and edge cases.

The current tests cover the happy paths well, but consider adding tests for:

  • Invalid contract addresses
  • Invalid token ID formats (mentioned in OperationalData context)
  • Empty or whitespace-only inputs
  • Maximum batch limits if applicable
  • Error message display

These would improve coverage and catch potential runtime issues.

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

30-56: Consider testing the validation logic for operational data.

Based on the relevant code snippets showing validateStrictAddress and filtering logic in transformToApiRequest, consider adding tests for:

  • Airdrop entries with invalid addresses (should be filtered out)
  • Airdrop entries with count ≤ 0 (should be filtered out)
  • Empty payment_address (should not add payment_info to metadata)
  • Empty arrays for airdrop_config and allowlist_batches

This would verify the validation logic works correctly and prevent invalid data from reaching the API.

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

576-583: Optional: Remove redundant dependency.

Line 581 includes state.externalMedia in the dependency array, but lines 577-580 already include the specific fields used by this effect (state.externalMedia.status, state.externalMedia.sanitizedHash, state.externalMedia.provider). The full object reference is unnecessary.

🔎 Suggested simplification
  }, [
    state.mediaSource,
    state.externalMedia.status,
    state.externalMedia.sanitizedHash,
    state.externalMedia.provider,
-   state.externalMedia,
    dispatch,
  ]);

598-609: Optional: Simplify trait spreading.

Lines 604-605 explicitly set title and description from traits, but line 603 already spreads ...traits, which includes these fields. The explicit assignments are redundant unless there's a specific reason to ensure these fields are present even if undefined in traits.

🔎 Suggested simplification (if no special handling needed)
  const getSubmissionData = useCallback(() => {
    const { traits, artworkUrl, operationalData } = state;
    return {
      imageUrl: artworkUrl,
-     traits: {
-       ...traits,
-       title: traits.title,
-       description: traits.description,
-     },
+     traits,
      operationalData,
    };
  }, [state]);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72e704c and 48d226d.

📒 Files selected for processing (10)
  • __tests__/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • __tests__/components/waves/memes/submission/components/AllowlistBatchManager.test.tsx
  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • components/waves/memes/submission/components/AllowlistBatchManager.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/types/OperationalData.ts
  • components/waves/memes/submission/utils/tokenParsing.ts
  • eslint.config.tight.mjs
  • scripts/wt-add.sh
🚧 Files skipped from review as they are similar to previous changes (4)
  • tests/components/waves/memes/submission/MemesArtSubmissionContainer.test.tsx
  • components/waves/memes/submission/utils/tokenParsing.ts
  • components/waves/memes/submission/components/AirdropConfig.tsx
  • components/waves/memes/submission/components/AllowlistBatchManager.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:

  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/AllowlistBatchManager.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/types/OperationalData.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:

  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/AllowlistBatchManager.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/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/AllowlistBatchManager.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/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/AllowlistBatchManager.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/types/OperationalData.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:

  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/AllowlistBatchManager.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/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/AllowlistBatchManager.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/types/OperationalData.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with React functional components and hooks

Files:

  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/AllowlistBatchManager.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/types/OperationalData.ts
**/{__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/AllowlistBatchManager.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/AllowlistBatchManager.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/hooks/useArtworkSubmissionMutation.test.tsx
  • __tests__/components/waves/memes/submission/components/AllowlistBatchManager.test.tsx
  • components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/types/OperationalData.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/useArtworkSubmissionForm.ts
  • components/waves/memes/submission/types/OperationalData.ts
🧠 Learnings (19)
📚 Learning: 2025-12-30T14:32:19.339Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.339Z
Learning: Applies to **/*.{test,spec}.{tsx,ts} : Mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/waves/memes/submission/hooks/useArtworkSubmissionMutation.test.tsx
📚 Learning: 2025-12-30T14:31:52.993Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:52.993Z
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/hooks/useArtworkSubmissionMutation.test.tsx
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
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/AllowlistBatchManager.test.tsx
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
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/AllowlistBatchManager.test.tsx
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
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/AllowlistBatchManager.test.tsx
  • eslint.config.tight.mjs
📚 Learning: 2025-11-25T08:36:24.149Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-11-25T08:36:24.149Z
Learning: When committing code changes, craft comprehensive Git commit messages summarizing the work done including both code implementation and rule adjustments, and consider if a Changeset is needed according to changeset.mdc

Applied to files:

  • scripts/wt-add.sh
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
Learning: Applies to __tests__/**/*.{ts,tsx,js},!**/__tests__/**,!**/__mocks__/**,!**/*.d.ts : Limit function cognitive complexity to 15 or less; extract deep ternaries (>3 levels)

Applied to files:

  • eslint.config.tight.mjs
📚 Learning: 2025-12-30T14:32:19.339Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.339Z
Learning: Applies to **/*.{js,ts,jsx,tsx} : Do not add `eslint-disable` comments unless explicitly instructed; prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions

Applied to files:

  • eslint.config.tight.mjs
📚 Learning: 2025-12-30T14:32:19.339Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.339Z
Learning: Applies to next.config.{ts,js,mjs} : Remove any `eslint` options from `next.config.*` files in Next.js 16

Applied to files:

  • eslint.config.tight.mjs
📚 Learning: 2025-12-30T14:31:52.993Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:52.993Z
Learning: Applies to next.config.{js,ts,mjs,mts} : With Next.js 16, `next lint` is removed. Use the ESLint CLI driven by `eslint-config-next` (flat config). Remove any `eslint` options from `next.config.*`.

Applied to files:

  • eslint.config.tight.mjs
📚 Learning: 2025-12-30T14:31:52.994Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:52.994Z
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:

  • eslint.config.tight.mjs
📚 Learning: 2025-12-30T14:32:19.339Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:19.339Z
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:

  • eslint.config.tight.mjs
📚 Learning: 2025-12-30T14:32:37.293Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-30T14:32:37.293Z
Learning: Applies to __tests__/**/*.{ts,tsx,js},!**/__tests__/**,!**/__mocks__/**,!**/*.d.ts : Catch errors only when meaningful; avoid empty catch blocks and always log errors with context

Applied to files:

  • eslint.config.tight.mjs
📚 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 TailwindCSS for styling in React components

Applied to files:

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

Applied to files:

  • eslint.config.tight.mjs
📚 Learning: 2025-12-30T14:31:52.993Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:52.993Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript with React functional components and hooks. Follow existing code style and naming conventions.

Applied to files:

  • eslint.config.tight.mjs
📚 Learning: 2025-12-30T14:31:52.993Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:52.993Z
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:

  • eslint.config.tight.mjs
📚 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} : Always add `readonly` before props in React components

Applied to files:

  • eslint.config.tight.mjs
📚 Learning: 2025-12-30T14:31:52.993Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-30T14:31:52.993Z
Learning: Applies to next.config.{js,ts,mjs,mts} : Enable React Compiler in `next.config.ts` once CI is green by setting `reactCompiler: true` to auto-memoize components and reduce manual `useMemo`/`useCallback` usage.

Applied to files:

  • eslint.config.tight.mjs
⏰ 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 (7)
eslint.config.tight.mjs (2)

182-185: LGTM! Appropriate relaxation for React patterns.

The ignoreArrowShorthand: true option allows arrow functions that return void, which is common in React event handlers and callbacks. This aligns well with modern React conventions.


488-494: LGTM! Reasonable exception for React components.

Disabling max-lines-per-function for TSX/JSX files is appropriate since React components often legitimately exceed 150 lines due to JSX markup and multiple render paths. This aligns with the "Chill" review mode and practical React development patterns.

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

1-46: LGTM! Well-structured type definitions.

The type definitions are clear, comprehensive, and follow good TypeScript practices:

  • Enum for metadata keys prevents string typos
  • Separation of AllowlistBatch (parsed) vs AllowlistBatchRaw (raw string) properly models the transformation
  • Constant AIRDROP_TOTAL provides a single source of truth
  • Interfaces are minimal and focused
components/waves/memes/submission/hooks/useArtworkSubmissionForm.ts (4)

46-46: LGTM! Improved type safety.

Replacing any with TraitsData[keyof TraitsData] provides proper type safety for trait field values, preventing type mismatches at compile time.


325-374: LGTM! Reducer logic for operational data is correct.

The reducer cases properly handle operational data updates with appropriate immutability patterns:

  • Arrays are replaced entirely (airdrop_config, allowlist_batches)
  • Objects are merged (payment_info, additional_media)
  • Simple values are replaced (commentary)

This approach is consistent with React state management best practices.


657-690: LGTM! Well-structured callback definitions.

All operational data setters are properly memoized with useCallback and have correct TypeScript typing. The dependency arrays are minimal and correct (only [dispatch]).


405-416: LGTM! Sensible default operational data.

The initial state provides a good starting point with:

  • One default airdrop entry (good UX, avoids empty state)
  • Empty strings for optional fields
  • Empty arrays for batch collections
  • Use of AIRDROP_TOTAL constant ensures consistency

@simo6529 simo6529 merged commit b434394 into main Jan 6, 2026
9 checks passed
@simo6529 simo6529 deleted the submission-additional-fields branch January 6, 2026 09:26
This was referenced Jan 12, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Apr 17, 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.

3 participants