Skip to content

[TASK-16569] Feat delight - Animations and Haptics#1401

Merged
Zishan-7 merged 6 commits intopeanut-wallet-devfrom
feat/delight
Nov 6, 2025
Merged

[TASK-16569] Feat delight - Animations and Haptics#1401
Zishan-7 merged 6 commits intopeanut-wallet-devfrom
feat/delight

Conversation

@Zishan-7
Copy link
Contributor

@Zishan-7 Zishan-7 commented Nov 5, 2025

Also contributes TASK-16453 TASK-16452 TASK-16454
image

@vercel
Copy link

vercel bot commented Nov 5, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
peanut-wallet Ready Ready Preview Comment Nov 6, 2025 10:58am

@Zishan-7 Zishan-7 changed the title [TASK-16569]Feat delight - Animations and Haptics [TASK-16569] Feat delight - Animations and Haptics Nov 5, 2025
@notion-workspace
Copy link

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 5, 2025

Walkthrough

Adds the "use-haptic" dependency and integrates haptic triggers across multiple mobile UI components, button API, payment/withdraw flows, claim flows, and several interactive elements; also introduces decorative animation assets and minor import cleanups.

Changes

Cohort / File(s) Change Summary
Dependency
package.json
Added dependency use-haptic (^1.1.11).
Button API
src/components/0_Bruddle/Button.tsx
Added disableHaptics?: boolean to ButtonProps; integrated useHaptic and conditional trigger on click.
Navigation & Mobile Home
src/app/(mobile-ui)/home/page.tsx, src/components/Global/WalletNavigation/index.tsx, src/components/Home/HomeHistory.tsx
Imported useHaptic and trigger haptics on navigation/link clicks and before opening Support modal.
Interactive Elements & Cards
src/components/ActionListCard/index.tsx, src/components/Home/HomeCarouselCTA/CarouselCTA.tsx, src/components/TransactionDetails/TransactionCard.tsx, src/components/Global/DirectSendQR/index.tsx
Added useHaptic and invoked triggerHaptic() on click handlers and QR processing.
Payment / Confirm / Status Flows
src/components/Payment/PaymentForm/index.tsx, src/components/Payment/Views/Confirm.payment.view.tsx, src/components/Payment/Views/Status.payment.view.tsx, src/app/(mobile-ui)/withdraw/crypto/page.tsx, src/app/[...recipient]/client.tsx
Integrated useHaptic triggers on success/transition/withdraw events; Status.payment.view.tsx also adds decorative animation image and positional layout changes (contains duplicate haptic useEffect).
Claim Flow & Onchain Views
src/components/Claim/Claim.tsx, src/components/Claim/Link/Onchain/Confirm.view.tsx, src/components/Claim/Link/Onchain/Success.view.tsx
Added useHaptic triggers on success flows; Success.view.tsx removed unused imports, added decorative peanut animation asset, and adjusted layout/positioning.
Minor imports / cleanup
src/components/Claim/Link/Onchain/Confirm.view.tsx, src/components/Claim/Link/Onchain/Success.view.tsx
Import list adjusted (added useEffect in Confirm.view.tsx; removed unused imports and reordered in Success.view.tsx).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to duplicate useEffect calls triggering haptics in src/components/Payment/Views/Status.payment.view.tsx.
  • Verify disableHaptics propagation and that components using Button opt into/avoid haptics where intended.
  • Check z-index, absolute positioning and visual layout changes in Success.view.tsx and Status.payment.view.tsx for regressions.

Possibly related PRs

Suggested reviewers

  • kushagrasarathe
  • Hugo0
  • jjramirezn

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: adding animations and haptics features to the mobile UI, which aligns with the extensive changes across multiple components for haptic feedback integration.
Description check ✅ Passed The description references related tasks and includes a visual screenshot, which relates to the UI/animation work, though it lacks detailed explanation of the specific changes made.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/delight

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0c64ad and a72d012.

📒 Files selected for processing (1)
  • src/components/Claim/Link/Onchain/Success.view.tsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Claim/Link/Onchain/Success.view.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Deploy-Preview

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
Contributor

@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

Caution

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

⚠️ Outside diff range comments (1)
src/components/0_Bruddle/Button.tsx (1)

193-205: Include all dependencies in handleClick
Line 200 should respect runtime toggles. Because disableHaptics and the hook-supplied triggerHaptic are omitted from the useCallback dependency array, the memoized handler keeps the initial values. If a caller flips disableHaptics at runtime, the button still fires—or still suppresses—haptics based on the stale closure. Please add both to the dependency list (and keep the lint rule quiet) so the click logic reflects current props and hook output.

         const handleClick = useCallback(
             (e: React.MouseEvent<HTMLButtonElement>) => {
                 if (longPress && !isLongPressed) {
                     return
                 }

                 if (!disableHaptics) {
                     triggerHaptic()
                 }

                 onClick?.(e)
             },
-            [longPress, isLongPressed, onClick]
+            [longPress, isLongPressed, onClick, disableHaptics, triggerHaptic]
         )
🧹 Nitpick comments (1)
src/components/Claim/Link/Onchain/Success.view.tsx (1)

179-185: Consider accessibility best practices for decorative images.

Since this animation is purely decorative and doesn't convey essential information, consider using an empty alt="" attribute or adding aria-hidden="true" to improve accessibility for screen reader users.

Apply this diff:

                <Image
                    src={chillPeanutAnim.src}
-                   alt="Peanut Mascot"
+                   alt=""
                    width={240}
                    height={240}
                    className="absolute -top-32 left-1/2 -z-10 h-60 w-60 -translate-x-1/2"
                />
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb1dec7 and 78bd649.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • package.json (1 hunks)
  • src/app/(mobile-ui)/home/page.tsx (3 hunks)
  • src/components/0_Bruddle/Button.tsx (4 hunks)
  • src/components/Claim/Link/Onchain/Confirm.view.tsx (3 hunks)
  • src/components/Claim/Link/Onchain/Success.view.tsx (2 hunks)
  • src/components/Global/DirectSendQR/index.tsx (3 hunks)
  • src/components/Global/WalletNavigation/index.tsx (3 hunks)
  • src/components/Payment/Views/Status.payment.view.tsx (4 hunks)
🧰 Additional context used
🧠 Learnings (18)
📚 Learning: 2024-10-18T01:51:35.247Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 458
File: src/components/Offramp/Confirm.view.tsx:141-141
Timestamp: 2024-10-18T01:51:35.247Z
Learning: The `handleConfirm` function in `src/components/Create/Link/Confirm.view.tsx` is separate from the one in `src/components/Offramp/Confirm.view.tsx` and does not need to be renamed when refactoring `handleConfirm` in `src/components/Offramp/Confirm.view.tsx`.

Applied to files:

  • src/components/Claim/Link/Onchain/Confirm.view.tsx
📚 Learning: 2025-09-18T09:30:42.901Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1230
File: src/app/(mobile-ui)/withdraw/page.tsx:92-97
Timestamp: 2025-09-18T09:30:42.901Z
Learning: In src/app/(mobile-ui)/withdraw/page.tsx, the useEffect that calls setShowAllWithdrawMethods(true) when amountFromContext exists is intentionally designed to run only on component mount (empty dependency array), not when amountFromContext changes. This is the correct behavior for the withdraw flow where showing all methods should only happen on initial load when an amount is already present.

Applied to files:

  • src/components/Claim/Link/Onchain/Confirm.view.tsx
  • src/components/Payment/Views/Status.payment.view.tsx
📚 Learning: 2024-11-18T21:36:11.486Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 535
File: src/components/Claim/Claim.tsx:142-146
Timestamp: 2024-11-18T21:36:11.486Z
Learning: In `src/components/Claim/Claim.tsx`, external calls like token price fetching and cross-chain details retrieval are already encapsulated within existing `try...catch` blocks, so additional error handling may be unnecessary.

Applied to files:

  • src/components/Claim/Link/Onchain/Confirm.view.tsx
  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2024-12-02T17:19:18.532Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 551
File: src/components/Request/Create/Views/Initial.view.tsx:151-156
Timestamp: 2024-12-02T17:19:18.532Z
Learning: In the `InitialView` component at `src/components/Request/Create/Views/Initial.view.tsx`, when setting the default chain and token in the `useEffect` triggered by `isPeanutWallet`, it's acceptable to omit the setters from the dependency array and not include additional error handling for invalid defaults.

Applied to files:

  • src/components/Claim/Link/Onchain/Confirm.view.tsx
  • src/components/Claim/Link/Onchain/Success.view.tsx
  • src/components/Payment/Views/Status.payment.view.tsx
📚 Learning: 2024-10-29T16:06:38.812Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 495
File: src/components/Create/useCreateLink.tsx:647-657
Timestamp: 2024-10-29T16:06:38.812Z
Learning: In the React code for `useCreateLink` in `src/components/Create/useCreateLink.tsx`, the `switchNetwork` function used within `useCallback` hooks is stable and does not need to be included in the dependency arrays.

Applied to files:

  • src/components/Claim/Link/Onchain/Confirm.view.tsx
  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2025-09-05T07:31:11.396Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1185
File: src/components/Claim/useClaimLink.tsx:14-0
Timestamp: 2025-09-05T07:31:11.396Z
Learning: In the peanut-ui codebase, `window.history.replaceState` is preferred over `router.replace` when immediate/synchronous URL parameter updates are required, as `router.replace` is asynchronous and doesn't guarantee instant URL changes that subsequent code can rely on. This pattern is used consistently across usePaymentInitiator.ts, Confirm.payment.view.tsx, and useClaimLink.tsx.

Applied to files:

  • src/components/Claim/Link/Onchain/Confirm.view.tsx
  • src/components/Claim/Link/Onchain/Success.view.tsx
  • src/components/Payment/Views/Status.payment.view.tsx
📚 Learning: 2024-10-08T20:13:42.967Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 413
File: src/components/Request/Pay/Views/Initial.view.tsx:71-72
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, it's acceptable to use the `!` operator in TypeScript to assert that `selectedTokenData` is not `null` or `undefined`, and potential runtime errors from accessing its properties without checks can be disregarded.

Applied to files:

  • src/components/Claim/Link/Onchain/Confirm.view.tsx
📚 Learning: 2025-10-29T11:27:59.248Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1368
File: src/components/Common/ActionList.tsx:109-111
Timestamp: 2025-10-29T11:27:59.248Z
Learning: In `src/components/Common/ActionList.tsx`, the `balance` from `useWallet()` hook is always in USDC (as a formatted string), making it directly comparable to USD amounts without conversion. The comparison `Number(balance) >= amountInUsd` is intentional and correct.

Applied to files:

  • src/components/Claim/Link/Onchain/Confirm.view.tsx
📚 Learning: 2024-10-23T09:38:27.670Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 469
File: src/app/request/pay/page.tsx:32-64
Timestamp: 2024-10-23T09:38:27.670Z
Learning: In `src/app/request/pay/page.tsx`, if `linkRes` is not OK in the `generateMetadata` function, the desired behavior is to use the standard title and preview image without throwing an error.

Applied to files:

  • src/components/Claim/Link/Onchain/Confirm.view.tsx
  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2025-09-08T03:13:09.111Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 1190
File: src/app/(mobile-ui)/qr-pay/page.tsx:156-176
Timestamp: 2025-09-08T03:13:09.111Z
Learning: In the peanut-ui mobile app, the `/qr-pay` route is only accessed through the DirectSendQR component which always includes the qrCode parameter in the URL when redirecting users to the QR pay page after scanning MERCADO_PAGO or PIX QR codes.

Applied to files:

  • src/components/Global/DirectSendQR/index.tsx
📚 Learning: 2025-09-08T03:13:09.111Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 1190
File: src/app/(mobile-ui)/qr-pay/page.tsx:156-176
Timestamp: 2025-09-08T03:13:09.111Z
Learning: In the peanut-ui mobile app, the `/qr-pay` route is only accessed through the DirectSendQR component which always includes the qrCode parameter in the URL when redirecting users to the QR pay page.

Applied to files:

  • src/components/Global/DirectSendQR/index.tsx
📚 Learning: 2025-10-08T17:13:13.155Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1299
File: src/app/(mobile-ui)/points/page.tsx:41-51
Timestamp: 2025-10-08T17:13:13.155Z
Learning: In `src/app/(mobile-ui)/points/page.tsx`, the icon name "invite-heart" is intentionally used (not "inviter-heart") when displaying who invited the current user, as this is a deliberate design choice despite semantic differences with UserHeader usage.

Applied to files:

  • src/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-07-24T13:26:10.290Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 1014
File: src/components/Claim/Link/Initial.view.tsx:413-413
Timestamp: 2025-07-24T13:26:10.290Z
Learning: In the peanut-ui repository, the change from `${SQUID_API_URL}/route` to `${SQUID_API_URL}/v2/route` in src/components/Claim/Link/Initial.view.tsx was a typo fix, not an API migration, as the codebase was already using Squid API v2.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2024-12-11T10:13:22.806Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 564
File: src/components/Request/Pay/Views/Initial.view.tsx:430-430
Timestamp: 2024-12-11T10:13:22.806Z
Learning: In the React TypeScript file `src/components/Request/Pay/Views/Initial.view.tsx`, when reviewing the `InitialView` component, do not flag potential issues with using non-null assertion `!` on the `slippagePercentage` variable, as handling undefined values in this context is considered out of scope.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
  • src/components/Payment/Views/Status.payment.view.tsx
📚 Learning: 2024-10-24T12:38:32.793Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 478
File: src/components/Request/Create/Views/Initial.view.tsx:81-89
Timestamp: 2024-10-24T12:38:32.793Z
Learning: In `src/components/Request/Create/Views/Initial.view.tsx`, the function `getTokenDetails` is a simple function that does not fetch from the network or perform asynchronous operations.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2025-08-22T07:28:32.281Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:522-545
Timestamp: 2025-08-22T07:28:32.281Z
Learning: In `src/components/Payment/PaymentForm/index.tsx`, the `handleCompleteDaimoPayment` function is only for updating payment status in the backend after a successful Daimo payment. Payment success/failure is handled by Daimo itself, so try/catch error handling and error display are not needed for backend sync failures - users shouldn't see errors if payment succeeded but database update failed.

Applied to files:

  • src/components/Payment/Views/Status.payment.view.tsx
📚 Learning: 2025-08-26T15:25:53.328Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1132
File: src/app/[...recipient]/client.tsx:394-397
Timestamp: 2025-08-26T15:25:53.328Z
Learning: In `src/components/Common/ActionListDaimoPayButton.tsx`, the `handleCompleteDaimoPayment` function should not display error messages to users when DB update fails because the Daimo payment itself has succeeded - showing errors would be confusing since the payment was successful.

Applied to files:

  • src/components/Payment/Views/Status.payment.view.tsx
📚 Learning: 2025-07-24T10:57:15.315Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1000
File: src/components/og/ProfileCardOG.tsx:0-0
Timestamp: 2025-07-24T10:57:15.315Z
Learning: In `src/components/og/ProfileCardOG.tsx`, the scribble image should have an empty alt attribute (alt="") to prevent layout issues if the image fails to load. Since it's a decorative element positioned absolutely over the username text, showing alt text would interfere with the layout and username display.

Applied to files:

  • src/components/Payment/Views/Status.payment.view.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Deploy-Preview
🔇 Additional comments (1)
src/components/Claim/Link/Onchain/Success.view.tsx (1)

12-20: Import changes look good.

The removal of unused imports and addition of necessary dependencies for the animation feature are appropriate.

Copy link
Contributor

@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

♻️ Duplicate comments (1)
src/components/Claim/Link/Onchain/Success.view.tsx (1)

186-192: Fix Image dimension mismatch to prevent layout shift.

The width={20} and height={20} props don't match the rendered size h-60 w-60 (240px × 240px). This mismatch causes Cumulative Layout Shift (CLS) issues as Next.js Image uses these dimensions for aspect ratio calculation.

Apply this diff to fix the dimensions:

                <Image
                    src={chillPeanutAnim.src}
                    alt="Peanut Mascot"
-                   width={20}
-                   height={20}
+                   width={240}
+                   height={240}
                    className="absolute -top-32 left-1/2 -z-10 h-60 w-60 -translate-x-1/2"
                />

Alternatively, if the intrinsic GIF size is 512×512 (as suggested by the filename), use:

                <Image
                    src={chillPeanutAnim.src}
                    alt="Peanut Mascot"
-                   width={20}
-                   height={20}
+                   width={512}
+                   height={512}
                    className="absolute -top-32 left-1/2 -z-10 h-60 w-60 -translate-x-1/2"
                />
🧹 Nitpick comments (1)
src/components/Home/HomeCarouselCTA/CarouselCTA.tsx (1)

43-54: Consider conditional haptic feedback based on action outcome.

Currently, triggerHaptic() fires for all click scenarios, including when isPermissionDenied is true. This creates a UX mismatch: the user receives tactile feedback suggesting successful interaction, but then sees an error modal instead.

Consider one of these approaches:

  • Trigger haptic only when the actual action succeeds (inside the onClick path)
  • Skip haptic when showing the permission-denied modal
  • Use different haptic patterns to distinguish success from error states
 const handleClick = async () => {
     try {
-        triggerHaptic()
         if (isPermissionDenied) {
             setShowPermissionDeniedModal(true)
         } else if (onClick) {
+            triggerHaptic()
             await onClick()
         }
     } catch (error) {
         console.error('Error handling CTA click:', error)
     }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78bd649 and 7a46b8d.

📒 Files selected for processing (13)
  • src/app/(mobile-ui)/withdraw/crypto/page.tsx (3 hunks)
  • src/app/[...recipient]/client.tsx (4 hunks)
  • src/components/ActionListCard/index.tsx (2 hunks)
  • src/components/Claim/Claim.tsx (3 hunks)
  • src/components/Claim/Link/Onchain/Confirm.view.tsx (1 hunks)
  • src/components/Claim/Link/Onchain/Success.view.tsx (4 hunks)
  • src/components/Common/ActionListDaimoPayButton.tsx (3 hunks)
  • src/components/Global/SoundPlayer.tsx (1 hunks)
  • src/components/Home/HomeCarouselCTA/CarouselCTA.tsx (3 hunks)
  • src/components/Home/HomeHistory.tsx (3 hunks)
  • src/components/Payment/PaymentForm/index.tsx (3 hunks)
  • src/components/Payment/Views/Confirm.payment.view.tsx (3 hunks)
  • src/components/TransactionDetails/TransactionCard.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Claim/Link/Onchain/Confirm.view.tsx
🧰 Additional context used
🧠 Learnings (28)
📚 Learning: 2025-08-22T07:28:32.281Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:522-545
Timestamp: 2025-08-22T07:28:32.281Z
Learning: In `src/components/Payment/PaymentForm/index.tsx`, the `handleCompleteDaimoPayment` function is only for updating payment status in the backend after a successful Daimo payment. Payment success/failure is handled by Daimo itself, so try/catch error handling and error display are not needed for backend sync failures - users shouldn't see errors if payment succeeded but database update failed.

Applied to files:

  • src/app/[...recipient]/client.tsx
  • src/components/Payment/Views/Confirm.payment.view.tsx
  • src/components/Payment/PaymentForm/index.tsx
  • src/components/Common/ActionListDaimoPayButton.tsx
📚 Learning: 2025-07-24T13:26:10.290Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 1014
File: src/components/Claim/Link/Initial.view.tsx:413-413
Timestamp: 2025-07-24T13:26:10.290Z
Learning: In the peanut-ui repository, the change from `${SQUID_API_URL}/route` to `${SQUID_API_URL}/v2/route` in src/components/Claim/Link/Initial.view.tsx was a typo fix, not an API migration, as the codebase was already using Squid API v2.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2024-11-18T21:36:11.486Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 535
File: src/components/Claim/Claim.tsx:142-146
Timestamp: 2024-11-18T21:36:11.486Z
Learning: In `src/components/Claim/Claim.tsx`, external calls like token price fetching and cross-chain details retrieval are already encapsulated within existing `try...catch` blocks, so additional error handling may be unnecessary.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
  • src/components/Claim/Claim.tsx
📚 Learning: 2024-12-02T17:19:18.532Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 551
File: src/components/Request/Create/Views/Initial.view.tsx:151-156
Timestamp: 2024-12-02T17:19:18.532Z
Learning: In the `InitialView` component at `src/components/Request/Create/Views/Initial.view.tsx`, when setting the default chain and token in the `useEffect` triggered by `isPeanutWallet`, it's acceptable to omit the setters from the dependency array and not include additional error handling for invalid defaults.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2025-09-05T07:31:11.396Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1185
File: src/components/Claim/useClaimLink.tsx:14-0
Timestamp: 2025-09-05T07:31:11.396Z
Learning: In the peanut-ui codebase, `window.history.replaceState` is preferred over `router.replace` when immediate/synchronous URL parameter updates are required, as `router.replace` is asynchronous and doesn't guarantee instant URL changes that subsequent code can rely on. This pattern is used consistently across usePaymentInitiator.ts, Confirm.payment.view.tsx, and useClaimLink.tsx.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
  • src/components/Payment/Views/Confirm.payment.view.tsx
📚 Learning: 2024-12-11T10:13:22.806Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 564
File: src/components/Request/Pay/Views/Initial.view.tsx:430-430
Timestamp: 2024-12-11T10:13:22.806Z
Learning: In the React TypeScript file `src/components/Request/Pay/Views/Initial.view.tsx`, when reviewing the `InitialView` component, do not flag potential issues with using non-null assertion `!` on the `slippagePercentage` variable, as handling undefined values in this context is considered out of scope.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
  • src/components/Payment/Views/Confirm.payment.view.tsx
📚 Learning: 2025-07-24T10:57:15.315Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1000
File: src/components/og/ProfileCardOG.tsx:0-0
Timestamp: 2025-07-24T10:57:15.315Z
Learning: In `src/components/og/ProfileCardOG.tsx`, the scribble image should have an empty alt attribute (alt="") to prevent layout issues if the image fails to load. Since it's a decorative element positioned absolutely over the username text, showing alt text would interfere with the layout and username display.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2025-08-14T09:20:37.231Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1089
File: src/components/LandingPage/hero.tsx:0-0
Timestamp: 2025-08-14T09:20:37.231Z
Learning: In the hero component at src/components/LandingPage/hero.tsx, the height was intentionally reduced from min-h-[100vh] to h-[90vh] to improve scrollability discoverability - so users can see there's more content below to scroll. The overflow-y-hidden is acceptable when other elements are adjusted to prevent clipping.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2024-10-29T16:06:38.812Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 495
File: src/components/Create/useCreateLink.tsx:647-657
Timestamp: 2024-10-29T16:06:38.812Z
Learning: In the React code for `useCreateLink` in `src/components/Create/useCreateLink.tsx`, the `switchNetwork` function used within `useCallback` hooks is stable and does not need to be included in the dependency arrays.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2024-10-23T09:38:27.670Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 469
File: src/app/request/pay/page.tsx:32-64
Timestamp: 2024-10-23T09:38:27.670Z
Learning: In `src/app/request/pay/page.tsx`, if `linkRes` is not OK in the `generateMetadata` function, the desired behavior is to use the standard title and preview image without throwing an error.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
  • src/components/Payment/Views/Confirm.payment.view.tsx
📚 Learning: 2024-10-24T12:38:32.793Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 478
File: src/components/Request/Create/Views/Initial.view.tsx:81-89
Timestamp: 2024-10-24T12:38:32.793Z
Learning: In `src/components/Request/Create/Views/Initial.view.tsx`, the function `getTokenDetails` is a simple function that does not fetch from the network or perform asynchronous operations.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
📚 Learning: 2025-10-02T15:23:01.513Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1266
File: src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx:46-57
Timestamp: 2025-10-02T15:23:01.513Z
Learning: In the withdraw flow at src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx, the points calculation query intentionally uses crypto.randomUUID() in the queryKey dependency array to bypass React Query caching, ensuring fresh points estimates on every render. This is the intended behavior.

Applied to files:

  • src/components/Claim/Link/Onchain/Success.view.tsx
  • src/app/(mobile-ui)/withdraw/crypto/page.tsx
📚 Learning: 2025-08-26T15:25:53.328Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1132
File: src/app/[...recipient]/client.tsx:394-397
Timestamp: 2025-08-26T15:25:53.328Z
Learning: In `src/components/Common/ActionListDaimoPayButton.tsx`, the `handleCompleteDaimoPayment` function should not display error messages to users when DB update fails because the Daimo payment itself has succeeded - showing errors would be confusing since the payment was successful.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
  • src/components/Payment/PaymentForm/index.tsx
  • src/components/Common/ActionListDaimoPayButton.tsx
📚 Learning: 2024-10-18T01:51:35.247Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 458
File: src/components/Offramp/Confirm.view.tsx:141-141
Timestamp: 2024-10-18T01:51:35.247Z
Learning: The `handleConfirm` function in `src/components/Create/Link/Confirm.view.tsx` is separate from the one in `src/components/Offramp/Confirm.view.tsx` and does not need to be renamed when refactoring `handleConfirm` in `src/components/Offramp/Confirm.view.tsx`.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
📚 Learning: 2024-10-07T15:25:45.170Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-10-07T15:25:45.170Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(...)` return strings, ensuring that `calculatedFee` consistently returns a string without the need for additional type conversion.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
  • src/components/Payment/PaymentForm/index.tsx
  • src/app/(mobile-ui)/withdraw/crypto/page.tsx
📚 Learning: 2024-10-07T15:28:25.280Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-10-07T15:28:25.280Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(estimatedGasCost, 3)` return strings, ensuring consistent return types for `calculatedFee`.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
📚 Learning: 2025-11-04T17:47:06.328Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1396
File: src/app/(mobile-ui)/home/page.tsx:295-304
Timestamp: 2025-11-04T17:47:06.328Z
Learning: In src/app/(mobile-ui)/home/page.tsx, when closing the KycCompletedModal, updateUserById is called without awaiting to provide instant feedback to the user. This fire-and-forget pattern for modal dismissals and UI preference updates is intentional and consistent across the codebase—user experience with instant UI feedback takes priority over waiting for backend sync operations.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
  • src/app/(mobile-ui)/withdraw/crypto/page.tsx
📚 Learning: 2024-10-08T20:13:42.967Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Request/Pay` components, the `tokenPrice` property in the `IPayScreenProps` interface is only relevant to these views. Other components using `IPayScreenProps` do not need to handle `tokenPriceData` when it's updated in these components.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
📚 Learning: 2025-09-18T09:30:42.901Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1230
File: src/app/(mobile-ui)/withdraw/page.tsx:92-97
Timestamp: 2025-09-18T09:30:42.901Z
Learning: In src/app/(mobile-ui)/withdraw/page.tsx, the useEffect that calls setShowAllWithdrawMethods(true) when amountFromContext exists is intentionally designed to run only on component mount (empty dependency array), not when amountFromContext changes. This is the correct behavior for the withdraw flow where showing all methods should only happen on initial load when an amount is already present.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
  • src/app/(mobile-ui)/withdraw/crypto/page.tsx
📚 Learning: 2024-10-04T13:10:49.199Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 413
File: src/components/Request/Pay/Views/Initial.view.tsx:71-72
Timestamp: 2024-10-04T13:10:49.199Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, it's acceptable to use the `!` operator in TypeScript to assert that `selectedTokenData` is not `null` or `undefined`, and potential runtime errors from accessing its properties without checks can be disregarded.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
📚 Learning: 2024-10-08T20:13:42.967Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 422
File: src/components/Request/Pay/Pay.tsx:113-123
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In the `PayRequestLink` component (`src/components/Request/Pay/Pay.tsx`), when resolving ENS names, handle errors by displaying an appropriate error message to the user if the ENS cannot be resolved.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
📚 Learning: 2024-10-18T08:54:22.142Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 458
File: src/components/Offramp/Confirm.view.tsx:96-96
Timestamp: 2024-10-18T08:54:22.142Z
Learning: In the `src/components/Offramp/Confirm.view.tsx` file, it's acceptable to include crass or informal language in code comments.

Applied to files:

  • src/components/Payment/Views/Confirm.payment.view.tsx
📚 Learning: 2025-05-15T14:47:26.891Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 857
File: src/hooks/useWebSocket.ts:77-82
Timestamp: 2025-05-15T14:47:26.891Z
Learning: The useWebSocket hook in src/hooks/useWebSocket.ts is designed to provide raw history entries, while the components using it (such as HomeHistory.tsx) are responsible for implementing deduplication logic based on UUID to prevent duplicate entries when combining WebSocket data with other data sources.

Applied to files:

  • src/components/Home/HomeHistory.tsx
📚 Learning: 2025-04-11T11:33:53.245Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 798
File: src/components/Home/HomeHistory.tsx:138-192
Timestamp: 2025-04-11T11:33:53.245Z
Learning: In the HomeHistory component, infinite scrolling is intentionally not implemented despite the presence of useInfiniteQuery and IntersectionObserver code. The component is designed to only display the first 5 entries with a "View all transactions" link for viewing the complete history.

Applied to files:

  • src/components/Home/HomeHistory.tsx
📚 Learning: 2025-08-26T17:38:37.055Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1132
File: src/components/Common/ActionList.tsx:153-156
Timestamp: 2025-08-26T17:38:37.055Z
Learning: In ActionList.tsx, when there are circular dependency concerns with ACTION_METHODS being imported by other components, the preferred solution is to move ACTION_METHODS to a separate constants file (like src/constants/actionlist.consts.ts) rather than using prop drilling. This centralizes constants management and creates a cleaner dependency graph.

Applied to files:

  • src/components/ActionListCard/index.tsx
📚 Learning: 2024-10-22T18:11:36.864Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 469
File: src/app/request/pay/page.tsx:32-49
Timestamp: 2024-10-22T18:11:36.864Z
Learning: In `src/app/request/pay/page.tsx`, the `id` parameter is accessed via `searchParams.id` in the `generateMetadata` function.

Applied to files:

  • src/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-05-22T15:38:48.586Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 869
File: src/app/(mobile-ui)/withdraw/page.tsx:82-88
Timestamp: 2025-05-22T15:38:48.586Z
Learning: The country-specific withdrawal route exists at src/app/(mobile-ui)/withdraw/[...country]/page.tsx and renders the AddWithdrawCountriesList component with flow="withdraw".

Applied to files:

  • src/app/(mobile-ui)/withdraw/crypto/page.tsx
📚 Learning: 2025-10-29T11:27:59.248Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1368
File: src/components/Common/ActionList.tsx:109-111
Timestamp: 2025-10-29T11:27:59.248Z
Learning: In `src/components/Common/ActionList.tsx`, the `balance` from `useWallet()` hook is always in USDC (as a formatted string), making it directly comparable to USD amounts without conversion. The comparison `Number(balance) >= amountInUsd` is intentional and correct.

Applied to files:

  • src/app/(mobile-ui)/withdraw/crypto/page.tsx
🧬 Code graph analysis (6)
src/app/[...recipient]/client.tsx (1)
src/components/Global/SoundPlayer.tsx (1)
  • playSoundByName (98-105)
src/components/Global/SoundPlayer.tsx (1)
src/hooks/useGetDeviceType.ts (1)
  • useDeviceType (37-42)
src/components/Payment/Views/Confirm.payment.view.tsx (1)
src/components/Global/SoundPlayer.tsx (1)
  • playSoundByName (98-105)
src/components/Payment/PaymentForm/index.tsx (1)
src/components/Global/SoundPlayer.tsx (1)
  • playSoundByName (98-105)
src/components/Claim/Claim.tsx (1)
src/components/Global/SoundPlayer.tsx (1)
  • playSoundByName (98-105)
src/components/Common/ActionListDaimoPayButton.tsx (1)
src/components/Global/SoundPlayer.tsx (1)
  • playSoundByName (98-105)
⏰ 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: Deploy-Preview
🔇 Additional comments (9)
src/components/Home/HomeHistory.tsx (1)

23-23: LGTM! Clean haptic feedback integration.

The implementation correctly integrates haptic feedback for the Activity navigation link. The hook usage follows React best practices, and triggering haptics on navigation is a solid UX pattern for mobile experiences.

Consider testing the haptic feedback on target devices (iOS/Android) to ensure it provides the expected tactile response and works correctly across different device configurations and system settings.

Also applies to: 44-44, 338-338

src/components/Home/HomeCarouselCTA/CarouselCTA.tsx (1)

11-11: LGTM! Clean haptic hook integration.

The import and hook usage follow standard React patterns correctly.

Also applies to: 36-36

src/app/(mobile-ui)/withdraw/crypto/page.tsx (1)

32-32: LGTM! The haptic feedback integration is approved.

The use-haptic library is a React hook that triggers device haptic feedback and supports iOS/Android. It's actively maintained with a recent release published on Apr 24, 2025. The latest version is 1.1.11.

Your implementation is clean and well-placed. The triggerHaptic() call on line 228 provides immediate tactile feedback when withdrawals succeed, enhancing the mobile user experience.

src/components/ActionListCard/index.tsx (3)

1-1: LGTM! Correct use of client directive.

The 'use client' directive is correctly placed and necessary for this component since it now uses the useHaptic hook, which requires client-side execution.


35-38: LGTM! Proper haptic feedback integration.

The haptic feedback is triggered at the right moment—immediately when the card is clicked and before the onClick callback executes. The implementation correctly respects the isDisabled prop (Line 42), ensuring haptic feedback doesn't fire for disabled cards.


8-8: LGTM! Clean integration of haptic hook.

The import and hook initialization follow React best practices. The hook is called unconditionally at the top level, and only the needed triggerHaptic function is destructured. The use-haptic library gracefully handles unsupported environments—it simply has no effect on devices or browsers lacking haptic support, rather than throwing errors.

src/components/TransactionDetails/TransactionCard.tsx (1)

24-24: LGTM! Clean haptic feedback integration with graceful fallback support.

The haptic feedback integration is minimal and well-placed. The hook is used correctly at the component level, and triggerHaptic() is invoked at the appropriate moment (on user click) before opening the drawer. The use-haptic library is designed as a progressive enhancement that fails silently on unsupported environments, so the core click functionality remains unaffected on desktop or older devices.

src/components/Claim/Link/Onchain/Success.view.tsx (2)

19-21: LGTM! Clean integration of haptic and animation assets.

The imports and hook initialization are properly structured. The useHaptic hook is correctly invoked at the component's top level.

Also applies to: 35-35


168-171: Wrap triggerHaptic with useCallback to ensure it only triggers on mount.

The triggerHaptic function from use-haptic is not guaranteed to have a stable reference across renders. Currently, it's destructured directly from the hook at line 35 and included in the dependency array at line 171. This causes the effect to re-run on every render instead of just on mount, contradicting the comment's intent.

Wrap it with useCallback at the hook initialization:

const { triggerHaptic: rawTriggerHaptic } = useHaptic()
const triggerHaptic = useCallback(() => rawTriggerHaptic(), [rawTriggerHaptic])

Then use the memoized version in your effect dependency array.

⛔ Skipped due to learnings
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 495
File: src/components/Create/useCreateLink.tsx:647-657
Timestamp: 2024-10-29T16:06:38.812Z
Learning: In the React code for `useCreateLink` in `src/components/Create/useCreateLink.tsx`, the `switchNetwork` function used within `useCallback` hooks is stable and does not need to be included in the dependency arrays.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1230
File: src/app/(mobile-ui)/withdraw/page.tsx:92-97
Timestamp: 2025-09-18T09:30:42.901Z
Learning: In src/app/(mobile-ui)/withdraw/page.tsx, the useEffect that calls setShowAllWithdrawMethods(true) when amountFromContext exists is intentionally designed to run only on component mount (empty dependency array), not when amountFromContext changes. This is the correct behavior for the withdraw flow where showing all methods should only happen on initial load when an amount is already present.
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 478
File: src/components/Request/Create/Views/Initial.view.tsx:48-128
Timestamp: 2024-10-24T12:40:15.006Z
Learning: When `handleOnNext` is deliberately refactored to avoid dependencies that change, it's acceptable to have an empty dependency array in `useCallback`.
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 631
File: src/context/kernelClient.context.tsx:88-124
Timestamp: 2025-01-16T13:13:48.615Z
Learning: In React useEffect hooks, when there's an early return condition and async operations, it's correct to have cleanup functions in both the early return and the final return to ensure proper cleanup in all scenarios.

@notion-workspace
Copy link

@notion-workspace
Copy link

@notion-workspace
Copy link

Copy link
Contributor

@kushagrasarathe kushagrasarathe left a comment

Choose a reason for hiding this comment

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

lgtm lfg

@Zishan-7 Zishan-7 merged commit 66f56d6 into peanut-wallet-dev Nov 6, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants