[TASK-16569] Feat delight - Animations and Haptics#1401
[TASK-16569] Feat delight - Animations and Haptics#1401Zishan-7 merged 6 commits intopeanut-wallet-devfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
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: 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 inhandleClick
Line 200 should respect runtime toggles. BecausedisableHapticsand the hook-suppliedtriggerHapticare omitted from theuseCallbackdependency array, the memoized handler keeps the initial values. If a caller flipsdisableHapticsat 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 addingaria-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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis 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.tsxsrc/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.tsxsrc/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.tsxsrc/components/Claim/Link/Onchain/Success.view.tsxsrc/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.tsxsrc/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.tsxsrc/components/Claim/Link/Onchain/Success.view.tsxsrc/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.tsxsrc/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.tsxsrc/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.
There was a problem hiding this comment.
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}andheight={20}props don't match the rendered sizeh-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 whenisPermissionDeniedis 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
onClickpath)- 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
📒 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.tsxsrc/components/Payment/Views/Confirm.payment.view.tsxsrc/components/Payment/PaymentForm/index.tsxsrc/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.tsxsrc/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.tsxsrc/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.tsxsrc/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.tsxsrc/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.tsxsrc/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.tsxsrc/components/Payment/PaymentForm/index.tsxsrc/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.tsxsrc/components/Payment/PaymentForm/index.tsxsrc/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.tsxsrc/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.tsxsrc/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-hapticlibrary 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 theuseHaptichook, 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
onClickcallback executes. The implementation correctly respects theisDisabledprop (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
triggerHapticfunction is destructured. Theuse-hapticlibrary 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. Theuse-hapticlibrary 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
useHaptichook is correctly invoked at the component's top level.Also applies to: 35-35
168-171: WraptriggerHapticwithuseCallbackto ensure it only triggers on mount.The
triggerHapticfunction fromuse-hapticis 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
useCallbackat 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.
This reverts commit 7a46b8d.
Also contributes TASK-16453 TASK-16452 TASK-16454
