Conversation
📝 WalkthroughWalkthroughThis PR introduces a preview flow for meme art submissions. It adds new React components to display preview cards (MemesSubmissionPreviewScreen, PreviewLeaderboardListCase, PreviewLeaderboardGalleryCase), utility modules to construct preview data (buildPreviewDrop, objectEntries), presentation presets for responsive widths, and integrates the preview mode into the existing submission container and additional info step with corresponding test coverage. Changes
Sequence DiagramsequenceDiagram
participant User
participant AdditionalInfoStep
participant MemesArtSubmissionContainer
participant buildPreviewDrop
participant MemesSubmissionPreviewScreen
participant Submit as Submit API
User->>AdditionalInfoStep: Click Preview Button
AdditionalInfoStep->>MemesArtSubmissionContainer: onPreview()
MemesArtSubmissionContainer->>buildPreviewDrop: buildPreviewDrop(wave, traits, media, connectedProfile)
buildPreviewDrop-->>MemesArtSubmissionContainer: ExtendedDrop with preview data
MemesArtSubmissionContainer->>MemesSubmissionPreviewScreen: Render with previewDrop
MemesSubmissionPreviewScreen-->>User: Display preview (list & gallery cards)
User->>MemesSubmissionPreviewScreen: Click "Back to Edit"
MemesSubmissionPreviewScreen->>MemesArtSubmissionContainer: onBackClick()
MemesArtSubmissionContainer->>AdditionalInfoStep: Exit preview mode
User->>MemesSubmissionPreviewScreen: Click "Submit Artwork"
MemesSubmissionPreviewScreen->>MemesArtSubmissionContainer: onSubmit()
MemesArtSubmissionContainer->>Submit: Submit with submission data
Submit-->>User: Submission confirmed
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Actionable comments posted: 2
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/MemesArtSubmissionContainer.tsx (1)
100-103:⚠️ Potential issue | 🟡 MinorRemove
console.warndebug artifact before merging.This logs a warning on every submission phase change in production, polluting the console and potentially leaking internal state labels to end-users.
🗑️ Proposed fix
const handlePhaseChange = useCallback((phase: SubmissionPhase) => { // Any additional phase-specific handling can be done here - console.warn(`Submission phase changed to: ${phase}`); }, []);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/waves/memes/submission/MemesArtSubmissionContainer.tsx` around lines 100 - 103, In handlePhaseChange (the useCallback for SubmissionPhase), remove the console.warn debug artifact so phase changes are no longer logged to the browser console; if you still need telemetry for debugging, replace it with a proper debug/logger call (e.g., use existing app logger like submissionLogger.debug or emit an analytics event) rather than console.warn to avoid leaking internal state in production.
🧹 Nitpick comments (5)
__tests__/components/waves/memes/submission/utils/buildPreviewDrop.test.ts (1)
38-41: LGTM — consider expanding coverage for null-profile author defaults and media URL selection.The test is intentionally scoped to the placeholder metrics. Optionally, adding assertions that cover the
connectedProfile: nullauthor defaults (e.g.author.handle === "preview-user") and the external-URL media path (e.g.parts[0].media[0].url === "https://example.com/art.png") would catch regressions in the broader construction logic without significant test complexity.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@__tests__/components/waves/memes/submission/utils/buildPreviewDrop.test.ts` around lines 38 - 41, Add assertions to the existing test that verify author defaults when connectedProfile is null and that the external media URL is selected: after constructing previewDrop assert that previewDrop.author.handle === "preview-user" (and other default author fields as needed) to cover the null-profile branch, and assert that previewDrop.parts[0].media[0].url === "https://example.com/art.png" to ensure the external-URL media path is used; locate these checks near the existing expectations for previewDrop.rating/rating_prediction/raters_count so they live in the same test scope.__tests__/components/waves/memes/submission/preview/MemesSubmissionPreviewScreen.test.tsx (1)
43-89: LGTM — tests correctly isolate the screen from its leaf components while verifying rendering order and interaction wiring.One minor note: the h5 heading assertions in lines 57–64 are coupled to the rendering internals of
PreviewLeaderboardListCase/PreviewLeaderboardGalleryCase(which are intentionally not mocked). If those component section titles ever change, this assertion will fail at a distance; adata-testidon the section wrappers would make the coupling explicit.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@__tests__/components/waves/memes/submission/preview/MemesSubmissionPreviewScreen.test.tsx` around lines 43 - 89, Add explicit data-testid attributes to the section wrapper elements inside the MemesSubmissionPreviewScreen (specifically on the containers rendered by PreviewLeaderboardListCase and PreviewLeaderboardGalleryCase) and update the test in MemesSubmissionPreviewScreen.test.tsx to assert presence/order using those testids (e.g., "preview-list-card" and "preview-gallery-card") rather than relying on h5 heading text; ensure the test still checks the overall heading "Submission Preview" and footer buttons wiring (onBackToEdit/onSubmit) remain unchanged.components/waves/memes/submission/preview/MemesSubmissionPreviewScreen.tsx (2)
27-31:exitanimation is a no-op without anAnimatePresenceparent.The
exit={{ opacity: 0, y: -20 }}will silently have no effect because the parent container (MemesArtSubmissionContainer) renders steps as{stepComponents[form.currentStep]}without anAnimatePresencewrapper. The mount animations (initial/animate) still work. Either addAnimatePresencein the container around the step render, or remove theexitprop to avoid misleading future readers.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/waves/memes/submission/preview/MemesSubmissionPreviewScreen.tsx` around lines 27 - 31, The exit animation on the motion.div in MemesSubmissionPreviewScreen is a no-op because the parent (MemesArtSubmissionContainer) renders steps as {stepComponents[form.currentStep]} without AnimatePresence; either wrap the step rendering in MemesArtSubmissionContainer with Framer Motion's <AnimatePresence> (ensuring keys on step components) to enable exit animations, or remove the exit prop from the motion.div in MemesSubmissionPreviewScreen to avoid misleading dead code—update the container to import AnimatePresence and wrap the dynamic step render, or delete the exit attribute accordingly.
58-65: Hardcodeddisabled={false}on the Submit button is easy to misread.
PrimaryButtondisables itself internally whenloadingis true (disabled || loading), so the behaviour is correct. However, future changes that need to truly disable the button without a loading state (e.g., a validation gate) will be missed because the prop is locked tofalse. Consider passing a computed value, or at minimum add an inline comment to signal intent.🔎 Suggested clarification
<PrimaryButton onClicked={onSubmit} - disabled={false} + disabled={false} // always enabled; `loading={isSubmitting}` handles the active-submission lockout loading={isSubmitting} padding="tw-px-6 tw-py-3" >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/waves/memes/submission/preview/MemesSubmissionPreviewScreen.tsx` around lines 58 - 65, The Submit button currently hardcodes disabled={false} on PrimaryButton (onClicked={onSubmit}, loading={isSubmitting}), which is confusing and will hide future validation-driven disabling; replace the hardcoded prop with a computed value (e.g., disabled={isFormInvalid} or disabled={shouldDisableSubmit}) that reflects validation/UX state, or remove the disabled prop and add a short inline comment next to PrimaryButton noting that the button is disabled via that computed prop and that loading is already handled by loading={isSubmitting}; update any references to isFormInvalid/shouldDisableSubmit as needed in the surrounding component logic.components/waves/memes/submission/MemesArtSubmissionContainer.tsx (1)
122-124:handleBackToEditleaves a stalepreviewDropin state; consider aligning withresetPreviewState.
handleBackToEditonly clearsisPreviewMode, whileresetPreviewStateclears both flags. The stale drop is never displayed (it's gated byisPreviewMode && previewDrop), but a subsequent re-preview call overwrites it, so there's no functional bug. For consistency and to avoid accidental future misuse, reuseresetPreviewStatehere.♻️ Proposed simplification
- const handleBackToEdit = useCallback(() => { - setIsPreviewMode(false); - }, []); + const handleBackToEdit = resetPreviewState;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/waves/memes/submission/MemesArtSubmissionContainer.tsx` around lines 122 - 124, handleBackToEdit currently only calls setIsPreviewMode(false) leaving previewDrop stale; change it to reuse the existing resetPreviewState helper so both isPreviewMode and previewDrop are cleared. Replace the body of handleBackToEdit to call resetPreviewState (or invoke the same logic that clears previewDrop and sets isPreviewMode) so previewDrop is not left in state; reference functions/variables: handleBackToEdit, resetPreviewState, previewDrop, isPreviewMode.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/waves/memes/submission/utils/buildPreviewDrop.ts`:
- Around line 91-94: The preview builder currently always pushes an
"additional_media" metadata entry using operationalData.additional_media in
buildPreviewDrop (metadata.push with data_key "additional_media"), causing
previews to include entries that the real submission path (see
useArtworkSubmissionMutation.ts which only pushes when
operationalData.additional_media is truthy) would omit; change buildPreviewDrop
to only add that metadata entry when operationalData.additional_media is
present/non-empty (mirror the same conditional used in
useArtworkSubmissionMutation.ts) so the preview matches the real submission
metadata.
- Around line 65-69: In buildPreviewDrop, the code assumes entry.address is
always a string and calls entry.address.trim(), which throws when address is
null/undefined; update the filtering logic in the operationalData.airdrop_config
processing to defensive-guard the address (e.g., use entry.address?.trim() ?? ""
or equivalent) before calling validateStrictAddress and computing trimmedAddress
so validateStrictAddress always receives a string; ensure this change is made
inside the function buildPreviewDrop where operationalData.airdrop_config is
filtered and the variable trimmedAddress is assigned.
---
Outside diff comments:
In `@components/waves/memes/submission/MemesArtSubmissionContainer.tsx`:
- Around line 100-103: In handlePhaseChange (the useCallback for
SubmissionPhase), remove the console.warn debug artifact so phase changes are no
longer logged to the browser console; if you still need telemetry for debugging,
replace it with a proper debug/logger call (e.g., use existing app logger like
submissionLogger.debug or emit an analytics event) rather than console.warn to
avoid leaking internal state in production.
---
Nitpick comments:
In
`@__tests__/components/waves/memes/submission/preview/MemesSubmissionPreviewScreen.test.tsx`:
- Around line 43-89: Add explicit data-testid attributes to the section wrapper
elements inside the MemesSubmissionPreviewScreen (specifically on the containers
rendered by PreviewLeaderboardListCase and PreviewLeaderboardGalleryCase) and
update the test in MemesSubmissionPreviewScreen.test.tsx to assert
presence/order using those testids (e.g., "preview-list-card" and
"preview-gallery-card") rather than relying on h5 heading text; ensure the test
still checks the overall heading "Submission Preview" and footer buttons wiring
(onBackToEdit/onSubmit) remain unchanged.
In `@__tests__/components/waves/memes/submission/utils/buildPreviewDrop.test.ts`:
- Around line 38-41: Add assertions to the existing test that verify author
defaults when connectedProfile is null and that the external media URL is
selected: after constructing previewDrop assert that previewDrop.author.handle
=== "preview-user" (and other default author fields as needed) to cover the
null-profile branch, and assert that previewDrop.parts[0].media[0].url ===
"https://example.com/art.png" to ensure the external-URL media path is used;
locate these checks near the existing expectations for
previewDrop.rating/rating_prediction/raters_count so they live in the same test
scope.
In `@components/waves/memes/submission/MemesArtSubmissionContainer.tsx`:
- Around line 122-124: handleBackToEdit currently only calls
setIsPreviewMode(false) leaving previewDrop stale; change it to reuse the
existing resetPreviewState helper so both isPreviewMode and previewDrop are
cleared. Replace the body of handleBackToEdit to call resetPreviewState (or
invoke the same logic that clears previewDrop and sets isPreviewMode) so
previewDrop is not left in state; reference functions/variables:
handleBackToEdit, resetPreviewState, previewDrop, isPreviewMode.
In `@components/waves/memes/submission/preview/MemesSubmissionPreviewScreen.tsx`:
- Around line 27-31: The exit animation on the motion.div in
MemesSubmissionPreviewScreen is a no-op because the parent
(MemesArtSubmissionContainer) renders steps as
{stepComponents[form.currentStep]} without AnimatePresence; either wrap the step
rendering in MemesArtSubmissionContainer with Framer Motion's <AnimatePresence>
(ensuring keys on step components) to enable exit animations, or remove the exit
prop from the motion.div in MemesSubmissionPreviewScreen to avoid misleading
dead code—update the container to import AnimatePresence and wrap the dynamic
step render, or delete the exit attribute accordingly.
- Around line 58-65: The Submit button currently hardcodes disabled={false} on
PrimaryButton (onClicked={onSubmit}, loading={isSubmitting}), which is confusing
and will hide future validation-driven disabling; replace the hardcoded prop
with a computed value (e.g., disabled={isFormInvalid} or
disabled={shouldDisableSubmit}) that reflects validation/UX state, or remove the
disabled prop and add a short inline comment next to PrimaryButton noting that
the button is disabled via that computed prop and that loading is already
handled by loading={isSubmitting}; update any references to
isFormInvalid/shouldDisableSubmit as needed in the surrounding component logic.

Summary by CodeRabbit
New Features
Bug Fixes