Skip to content

fix: camera & dark mode revert#1433

Open
Hugo0 wants to merge 4 commits intodevfrom
fix/camera-and-dark-fixes
Open

fix: camera & dark mode revert#1433
Hugo0 wants to merge 4 commits intodevfrom
fix/camera-and-dark-fixes

Conversation

@Hugo0
Copy link
Contributor

@Hugo0 Hugo0 commented Nov 8, 2025

  1. QR scanner improvements
  2. revert bad dark mode changes
  3. add camera pre-flight checks

@vercel
Copy link

vercel bot commented Nov 8, 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 8, 2025 10:28pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 8, 2025

Walkthrough

Adds pre-flight camera/microphone readiness checks and UI for KYC flows: new media permission utilities and types, a useKycCameraCheck hook, CameraPermissionWarningModal component, integrations into Bridge and Manteca KYC modals, Manteca flow now returns KYC URL, and dark-mode/tailwind CSS updates.

Changes

Cohort / File(s) Summary
Media utilities
src/utils/mediaPermissions.utils.ts
New utilities and types: MediaCheckResult, checkMediaAvailability(), isRestrictedEnvironment(), checkKycMediaReadiness() for capability/environment checks and user-facing messages.
KYC camera hook
src/hooks/useKycCameraCheck.ts
New exported UseKycCameraCheckOptions and useKycCameraCheck(...) hook that runs pre-flight checks, manages showCameraWarning/mediaCheckResult/isChecking, and exposes handlers (handleVerifyClick, handleContinueAnyway, handleOpenInBrowser).
Camera permission modal component
src/components/Kyc/CameraPermissionWarningModal.tsx
New client React component (default export) rendering an ActionModal using mediaCheckResult to derive title/description and conditional CTAs ("Open in Browser" always; "Try Anyway" only for non-error warnings).
KYC modal integrations
src/components/Kyc/InitiateBridgeKYCModal.tsx, src/components/Kyc/InitiateMantecaKYCModal.tsx
Integrated useKycCameraCheck, replaced direct initiation with hook flow, added showCameraWarning/mediaCheckResult state, gated ActionModal/iframe visibility while warnings are shown, and wired CameraPermissionWarningModal handlers.
Manteca flow return shape
src/hooks/useMantecaKycFlow.ts
openMantecaKycFlow success return now includes { success: true, url } (was just { success: true }).
Global styles & tailwind
src/styles/globals.css, tailwind.config.js
Removed forced light-mode override, added dark-mode variants for several utilities, and changed Tailwind darkMode to ['class', '[data-theme="dark"]'].
Modal layout tweak
src/components/Global/Modal/index.tsx
Always apply sm:m-auto and sm:self-auto to Dialog.Panel (class composition reordered).
Class reorder (cosmetic)
src/components/Global/ValidatedInput/index.tsx
Reordered Tailwind utility classes in a cancel button className only (no behavior change).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to focus extra attention:
    • src/utils/mediaPermissions.utils.ts: device enumeration logic, error handling, userAgent heuristics in isRestrictedEnvironment, and user-facing message correctness.
    • src/hooks/useKycCameraCheck.ts: async flow and race conditions (use of isChecking), extraction of KYC URL from multiple payload shapes, and correct sequencing of onInitiateKyc / saveRedirect / onClose.
    • src/components/Kyc/CameraPermissionWarningModal.tsx: conditional CTA construction, accessibility props, and correct handling of mediaCheckResult.severity.
    • Integration points in InitiateMantecaKYCModal / InitiateBridgeKYCModal: iframe visibility gating and handling of the new { url } return shape.

Possibly related PRs

  • Fix/camera and dark fixes #1431 — Changes to camera/microphone permission handling and related UI (touches globals.css and modal layout), likely related to this camera-permissions flow and styling updates.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'fix: camera & dark mode revert' is vague and misleading; it uses '&' as shorthand and 'revert' suggests undoing changes, but the PR actually implements new camera checks and enables dark mode. Use a more specific title like 'feat: add camera permission checks and dark mode support' to accurately reflect that this introduces new features rather than reverting them.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess whether it relates to the changeset. Add a description explaining the purpose and scope of changes, such as the camera permission validation flow and dark mode configuration updates.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ 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 fix/camera-and-dark-fixes

Comment @coderabbitai help to get the list of available commands and usage tips.

@Hugo0
Copy link
Contributor Author

Hugo0 commented Nov 8, 2025

@coderabbitai review in depth.

Evaluate:

  • risk of introducing new bugs and breaking existing functionality
  • do the new preflight checks introduce waiting time? can it degrade user experience?
  • performance impact and latency
  • edge cases
  • code quality and DRY

Also, write a very concise testing guide for QA

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: 5

Caution

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

⚠️ Outside diff range comments (1)
src/components/Kyc/InitiateBridgeKYCModal.tsx (1)

1-1: Fix Prettier formatting.

The pipeline detected code style issues.

Run the following command to fix:

pnpm prettier --write src/components/Kyc/InitiateBridgeKYCModal.tsx
🧹 Nitpick comments (2)
src/hooks/useMantecaKycFlow.ts (1)

79-100: Consider adding an explicit return type annotation.

Adding a return type would make the discriminated union pattern more explicit and provide better IntelliSense for callers.

const openMantecaKyc = useCallback(async (countryParam?: CountryData): Promise<
    | { success: true; url: string }
    | { success: false; error: string }
> => {

Based on learnings.

src/components/Kyc/InitiateMantecaKYCModal.tsx (1)

50-62: Recommend stabilizing the onKycSuccess callback.

The useEffect includes onKycSuccess in its dependency array. If this callback isn't memoized by the parent, the message event handler will be re-registered on every render, which is inefficient.

Consider either:

  1. Wrapping onKycSuccess in useCallback at the call site, or
  2. Using a ref pattern to avoid the dependency:
+    const onKycSuccessRef = useRef(onKycSuccess)
+    useEffect(() => {
+        onKycSuccessRef.current = onKycSuccess
+    }, [onKycSuccess])
+
     useEffect(() => {
         const handleMessage = (event: MessageEvent) => {
             if (event.data.source === 'peanut-kyc-success') {
-                onKycSuccess?.()
+                onKycSuccessRef.current?.()
             }
         }
 
         window.addEventListener('message', handleMessage)
 
         return () => {
             window.removeEventListener('message', handleMessage)
         }
-    }, [onKycSuccess])
+    }, [])
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 702c44e and 3c1bb33.

📒 Files selected for processing (8)
  • src/components/Kyc/CameraPermissionWarningModal.tsx (1 hunks)
  • src/components/Kyc/InitiateBridgeKYCModal.tsx (4 hunks)
  • src/components/Kyc/InitiateMantecaKYCModal.tsx (5 hunks)
  • src/hooks/useKycCameraCheck.ts (1 hunks)
  • src/hooks/useMantecaKycFlow.ts (1 hunks)
  • src/styles/globals.css (3 hunks)
  • src/utils/mediaPermissions.utils.ts (1 hunks)
  • tailwind.config.js (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
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.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 942
File: src/components/AddMoney/consts/index.ts:2151-2162
Timestamp: 2025-06-30T10:44:08.048Z
Learning: Hugo0 often agrees with refactoring suggestions but defers implementation due to time constraints, preferring to track improvements as follow-up issues when they're part of larger architectural changes.
📚 Learning: 2025-08-11T10:35:02.715Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1078
File: src/hooks/useKycFlow.ts:129-141
Timestamp: 2025-08-11T10:35:02.715Z
Learning: In the KYC flow implementation in `src/hooks/useKycFlow.ts`, when Terms of Service (ToS) is accepted, there will always be a KYC link available in the `apiResponse`. The system ensures this invariant, so defensive checks for missing KYC links after ToS acceptance are unnecessary.

Applied to files:

  • src/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateBridgeKYCModal.tsx
  • src/hooks/useMantecaKycFlow.ts
📚 Learning: 2025-06-22T16:10:53.167Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 915
File: src/hooks/useKycFlow.ts:96-124
Timestamp: 2025-06-22T16:10:53.167Z
Learning: The `initiateKyc` function in `src/app/actions/users.ts` already includes comprehensive error handling with try-catch blocks and returns structured responses with either `{ data }` or `{ error }` fields, so additional try-catch blocks around its usage are not needed.

Applied to files:

  • src/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateMantecaKYCModal.tsx
  • src/hooks/useMantecaKycFlow.ts
📚 Learning: 2025-08-20T09:08:19.266Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1112
File: src/components/Claim/Link/views/BankFlowManager.view.tsx:336-343
Timestamp: 2025-08-20T09:08:19.266Z
Learning: In the KYC flow implementation, `setJustCompletedKyc` must be called after `await fetchUser()` in the `handleKycSuccess` callback. Setting `justCompletedKyc` before fetching the user would cause a re-fetching loop because `handleKycSuccess` is set in a useEffect inside the KYC hook, which would cause the UI flow to get stuck in one view.

Applied to files:

  • src/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateMantecaKYCModal.tsx
  • src/components/Kyc/InitiateBridgeKYCModal.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/Kyc/InitiateMantecaKYCModal.tsx
  • src/components/Kyc/InitiateBridgeKYCModal.tsx
📚 Learning: 2025-05-21T18:52:22.958Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 870
File: src/styles/globals.css:18-18
Timestamp: 2025-05-21T18:52:22.958Z
Learning: In the peanut-ui project, using `-webkit-tap-highlight-color: none` fixed an issue with blue highlights appearing when tapping inputs on mobile devices, even though `none` is not a technically valid value for this CSS property according to specifications. The valid alternative would be `transparent`.

Applied to files:

  • src/styles/globals.css
🧬 Code graph analysis (4)
src/components/Kyc/CameraPermissionWarningModal.tsx (3)
src/utils/mediaPermissions.utils.ts (1)
  • MediaCheckResult (6-12)
src/components/Global/ActionModal/index.tsx (1)
  • ActionModalButtonProps (8-12)
src/components/Global/Icons/Icon.tsx (1)
  • IconName (70-136)
src/hooks/useKycCameraCheck.ts (1)
src/utils/mediaPermissions.utils.ts (2)
  • MediaCheckResult (6-12)
  • checkKycMediaReadiness (103-117)
src/components/Kyc/InitiateMantecaKYCModal.tsx (2)
src/hooks/useKycCameraCheck.ts (1)
  • useKycCameraCheck (14-64)
src/components/Kyc/CameraPermissionWarningModal.tsx (1)
  • CameraPermissionWarningModal (19-79)
src/components/Kyc/InitiateBridgeKYCModal.tsx (3)
src/hooks/useKycCameraCheck.ts (1)
  • useKycCameraCheck (14-64)
src/utils/general.utils.ts (1)
  • saveRedirectUrl (786-790)
src/components/Kyc/CameraPermissionWarningModal.tsx (1)
  • CameraPermissionWarningModal (19-79)
🪛 GitHub Actions: Tests
src/components/Kyc/CameraPermissionWarningModal.tsx

[warning] 1-1: Code style issues found by Prettier. Run 'pnpm prettier --write' to fix.

src/components/Kyc/InitiateBridgeKYCModal.tsx

[warning] 1-1: Code style issues found by Prettier. Run 'pnpm prettier --write' to fix.

⏰ 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 (8)
src/hooks/useMantecaKycFlow.ts (1)

92-92: LGTM! Returning the URL enables pre-flight checks.

Exposing the url in the return value allows callers to perform camera permission checks or other validations before opening the iframe, which aligns well with the new KYC camera check flow.

tailwind.config.js (1)

6-6: LGTM! Dark mode configuration correctly enabled.

The dual-selector approach (class and data-theme attribute) provides flexible dark mode support throughout the application.

src/styles/globals.css (2)

393-393: LGTM! Consistent dark mode styling.

The dark mode variants for .panel are properly configured with matching border, background, and ring colors.


428-428: LGTM! Dark mode variants properly applied.

The .border-rounded and .ring-sm classes now correctly support dark mode with appropriate color adjustments.

Also applies to: 432-432

src/components/Kyc/CameraPermissionWarningModal.tsx (1)

19-79: LGTM - Well-structured camera permission warning flow.

The component correctly handles different severity levels (error vs. warning) and provides appropriate CTAs. The conditional "Try Anyway" button (only for warnings) is a good UX pattern.

src/utils/mediaPermissions.utils.ts (3)

18-83: LGTM - Comprehensive media capability detection.

The checkMediaAvailability function correctly handles various failure modes with appropriate severity levels. The decision to mark missing microphone as a warning (not error) is reasonable, as some KYC flows may proceed without it.


89-98: LGTM - Restricted environment detection.

The user agent patterns for iOS WebView and in-app browsers are appropriate for detecting environments where iframe camera/mic access is typically restricted.


103-117: LGTM - Effective combined readiness check.

The function appropriately combines capability checks with environment detection to provide a complete picture of KYC readiness.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 8, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Get PR details
gh pr view 1433 --json title,body,files,additions,deletions,changedFiles

# Get the diff for the PR
gh pr diff 1433

# Get the list of files changed
gh pr view 1433 --json files --jq '.files[].path'

Length of output: 21765


🏁 Script executed:

#!/bin/bash

# Read the key implementation files for detailed analysis
echo "=== mediaPermissions.utils.ts ==="
cat src/utils/mediaPermissions.utils.ts

echo -e "\n=== useKycCameraCheck.ts ==="
cat src/hooks/useKycCameraCheck.ts

echo -e "\n=== CameraPermissionWarningModal.tsx ==="
cat src/components/Kyc/CameraPermissionWarningModal.tsx

echo -e "\n=== Check how Bridge KYC flow was modified ==="
cat src/components/Kyc/InitiateBridgeKYCModal.tsx

echo -e "\n=== Check how Manteca KYC flow was modified ==="
cat src/components/Kyc/InitiateMantecaKYCModal.tsx

echo -e "\n=== Check if IframeWrapper accepts visible prop ==="
rg -n "interface.*Props" src/components/Global/IframeWrapper -A 10

Length of output: 18787


🏁 Script executed:

#!/bin/bash

# Check IframeWrapper component definition
echo "=== IframeWrapper component ==="
cat src/components/Global/IframeWrapper/index.tsx 2>/dev/null || cat src/components/Global/IframeWrapper.tsx 2>/dev/null || fd -t f "IframeWrapper" --exec cat {}

# Check useBridgeKycFlow hook to understand return structure
echo -e "\n=== useBridgeKycFlow hook ==="
cat src/hooks/useBridgeKycFlow.ts

# Check useMantecaKycFlow hook 
echo -e "\n=== useMantecaKycFlow hook (snippet) ==="
head -80 src/hooks/useMantecaKycFlow.ts

# Check if there are any existing uses of setShowCameraWarning in Bridge modal
echo -e "\n=== Check setShowCameraWarning usage ==="
rg -n "setShowCameraWarning" src/components/Kyc/

Length of output: 18893


@Hugo0, I've completed the in-depth review. Here's my comprehensive analysis:

🚨 Critical Issues

1. Runtime Error - Missing State Setter

Severity: CRITICAL 🔴

Both InitiateBridgeKYCModal.tsx (line 92) and InitiateMantecaKYCModal.tsx (line 94) call setShowCameraWarning(false), but useKycCameraCheck hook does not expose this setter:

// What's returned by the hook:
return {
    showCameraWarning,
    mediaCheckResult,
    handleVerifyClick,
    handleContinueAnyway,
    handleOpenInBrowser,
}
// ❌ setShowCameraWarning is NOT exposed!

Fix required:

// In useKycCameraCheck.ts
return {
    showCameraWarning,
    setShowCameraWarning, // ← Add this
    mediaCheckResult,
    handleVerifyClick,
    handleContinueAnyway,
    handleOpenInBrowser,
}

2. Double API Call Issue

Severity: HIGH 🟠

In useKycCameraCheck.ts lines 23-35, when media check fails, onInitiateKyc() is called to get the URL. Then if the check passes at line 38, it's called again:

if (!mediaCheck.supported || mediaCheck.severity === 'warning') {
    const result = await onInitiateKyc()  // ← First call
    // ...
}
// Media check passed or couldn't get URL, proceed normally
const result = await onInitiateKyc()  // ← Second call!

This means in the "show warning" path, the KYC is initiated twice, wasting an API call.

Fix: Store the result and reuse it:

const handleVerifyClick = async () => {
    const mediaCheck = await checkKycMediaReadiness()
    
    if (!mediaCheck.supported || mediaCheck.severity === 'warning') {
        setMediaCheckResult(mediaCheck)
        const result = await onInitiateKyc()
        if (result?.success) {
            const url = result.url || result.data?.kycLink
            if (url) {
                setKycUrlForBrowser(url)
                setShowCameraWarning(true)
                return { shouldProceed: false }
            }
        }
        // If URL retrieval failed but warning needed, return here
        return { shouldProceed: false }
    }

    // Only call if not already called above
    const result = await onInitiateKyc()
    return { shouldProceed: result?.success ?? false }
}

3. Unstable useEffect Dependency

Severity: MEDIUM 🟡

InitiateMantecaKYCModal.tsx line 62:

useEffect(() => {
    // ...
}, [onKycSuccess])  // ← May cause unnecessary re-runs

If parent doesn't memoize onKycSuccess, this effect runs on every render.

⚠️ UX & Performance Issues

4. Added Latency on Button Click

Severity: MEDIUM 🟡

checkKycMediaReadiness() calls navigator.mediaDevices.enumerateDevices() which can take 100-500ms on some devices/browsers. This creates noticeable lag when clicking "Verify now".

Impact: Button feels unresponsive, no loading indicator shown during check.

Recommendation: Add immediate loading state:

const handleVerifyClick = async () => {
    addParamStep('bank')
    setIsLoading(true)  // ← Add immediate feedback
    const result = await checkAndInitiate()
    setIsLoading(false)
    // ...
}

5. User Stuck in Limbo Edge Case

Severity: MEDIUM 🟡

If media check triggers warning but URL fetch fails (line 26-27), the warning modal won't show, but KYC won't proceed either. User is stuck with no feedback.

6. Dark Mode Re-enabled Without Gradual Rollout

Severity: MEDIUM 🟡

tailwind.config.js changes from darkMode: false to darkMode: ['class', '[data-theme="dark"]']. This affects the entire app. The CSS changes in globals.css add dark mode styles, but this is a high-risk change that could cause visual regressions across many components.

Risk: Unintended dark mode activation if any element has class="dark" or data-theme="dark".

🐛 Edge Cases & Technical Issues

7. enumerateDevices() Limitations

Severity: LOW 🟢

enumerateDevices() only lists hardware, it doesn't check:

  • If permissions are granted
  • If devices actually work
  • If they're being used by another app

A camera could be listed but still fail when accessed.

8. Brittle User-Agent Detection

Severity: LOW 🟢

isRestrictedEnvironment() uses regex matching:

const iosWebView = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(ua)
const inAppBrowser = /FBAN|FBAV|Instagram|Twitter|Line|WhatsApp/i.test(ua)

Issues:

  • UA strings can be spoofed
  • New in-app browsers won't be detected
  • False positives possible

9. Missing Error Boundary

Severity: LOW 🟢

If checkKycMediaReadiness() throws unexpectedly, it could crash the component. The try-catch in checkMediaAvailability() helps, but the caller should also handle errors.

📋 Code Quality & DRY

10. Code Duplication

Severity: LOW 🟢

The integration pattern in InitiateBridgeKYCModal and InitiateMantecaKYCModal is nearly identical (~20 lines duplicated). Consider extracting to a shared wrapper component.

11. Minor: Class Order Inconsistency

The CSS changes reorder Tailwind classes (e.g., sm:m-auto sm:self-autodark:bg-n-1 sm:m-auto sm:self-auto). Not a bug, but inconsistent with the original responsive-first approach.


✅ Positive Aspects

  1. Good separation of concerns - media check logic isolated in utils
  2. Defensive programming - try-catch blocks handle errors
  3. Clear user messaging - modal provides actionable options
  4. Type safety - proper TypeScript interfaces

🧪 QA Testing Guide

Test Scenarios:

1. Happy Path - Normal Device

  • Device: Desktop with webcam
  • Steps:
    1. Click "Verify now" on Bridge KYC modal
    2. Should proceed directly to KYC iframe (no warning)
    3. Complete verification
  • Expected: Smooth flow, no delays

2. No Camera Detected

  • Device: Desktop without camera OR deny camera permission in browser
  • Steps:
    1. Click "Verify now"
    2. Should show error modal: "Camera or Microphone Required"
    3. Only "Open in Browser" button visible (no "Try Anyway")
    4. Click "Open in Browser"
  • Expected: Opens KYC in new tab, modal closes

3. In-App Browser (Instagram/Facebook)

  • Device: iPhone, open link in Instagram/Facebook in-app browser
  • Steps:
    1. Click "Verify now"
    2. Should show warning: "Camera Access May Be Limited"
    3. Two options: "Open in Browser" and "Try Anyway"
    4. Test both paths
  • Expected: Warning appears, both options work

4. No Microphone (Warning Path)

  • Device: Desktop with camera but no microphone
  • Steps:
    1. Click "Verify now"
    2. Should show warning (not error)
    3. Can proceed with "Try Anyway"
  • Expected: User can continue despite warning

5. Manteca KYC Flow

  • Repeat tests 1-4 for Manteca KYC (country selection flow)
  • Expected: Same behavior as Bridge KYC

6. Dark Mode Check

  • Toggle dark mode (if applicable)
  • Check modals, inputs, panels render correctly
  • Verify text contrast is readable
  • Expected: All UI elements visible and styled correctly

7. Performance Test

  • Device: Various (slow Android, fast desktop)
  • Metric: Time between clicking "Verify now" and modal appearing
  • Expected: < 1 second on all devices

8. Edge Cases

  • Test with VPN/location changes
  • Test with browser extensions that block media
  • Test rapid clicking "Verify now" (race condition)
  • Test closing warning modal then clicking "Verify now" again

9. Regression Testing

  • Verify existing KYC flows still work
  • Check that users who already completed KYC aren't affected
  • Test all dark mode UI across the app (high risk change)

🎯 Risk Summary

Category Risk Level Notes
Breaking existing functionality 🔴 HIGH Critical bug will cause runtime errors
UX degradation 🟡 MEDIUM 100-500ms latency added, but flow improves for restricted devices
Performance impact 🟡 MEDIUM One async API call per verification attempt
Edge cases 🟡 MEDIUM Several edge cases not fully handled
Code quality 🟢 LOW Good structure, minor DRY violations

💡 Recommendations

  1. MUST FIX BEFORE MERGE: Export setShowCameraWarning from hook
  2. SHOULD FIX: Eliminate double API call
  3. CONSIDER: Add loading indicator during media check
  4. CONSIDER: Memoize onKycSuccess callback in parent components
  5. CONSIDER: Feature flag dark mode changes for gradual rollout

Let me know if you want me to create follow-up issues for any of these findings! 🚀


🧠 Learnings used
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 852
File: src/hooks/useTransactionHistory.ts:177-239
Timestamp: 2025-05-14T21:16:06.369Z
Learning: When reviewing code, pay attention to and resolve CodeRabbit comments as they can contain useful refactoring suggestions and insights.

Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 594
File: src/components/Request/Pay/Views/Initial.view.tsx:188-213
Timestamp: 2024-12-31T15:08:15.640Z
Learning: Always resolve coderabbit comments when reviewing code, since they can contain useful suggestions.

Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 942
File: src/components/AddMoney/consts/index.ts:2151-2162
Timestamp: 2025-06-30T10:44:08.048Z
Learning: Hugo0 often agrees with refactoring suggestions but defers implementation due to time constraints, preferring to track improvements as follow-up issues when they're part of larger architectural changes.

@Hugo0
Copy link
Contributor Author

Hugo0 commented Nov 8, 2025

@coderabbitai review in depth again.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 8, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Get the current state of key files to check if issues were addressed
echo "=== useKycCameraCheck.ts current state ==="
cat src/hooks/useKycCameraCheck.ts

echo -e "\n=== InitiateBridgeKYCModal.tsx current state ==="
cat src/components/Kyc/InitiateBridgeKYCModal.tsx

echo -e "\n=== InitiateMantecaKYCModal.tsx current state ==="
cat src/components/Kyc/InitiateMantecaKYCModal.tsx

echo -e "\n=== Check latest commit messages ==="
git log --oneline -10

echo -e "\n=== Check PR diff summary ==="
gh pr diff 1433 --stat

Length of output: 13775


@Hugo0, excellent work on the fixes! Here's my updated in-depth review:

✅ Critical Issues RESOLVED

1. Missing State Setter - FIXED

The useKycCameraCheck hook now properly exports setShowCameraWarning (line 70). The runtime error is resolved.

2. Double API Call - FIXED

The logic was elegantly refactored (lines 23-45). Now onInitiateKyc() is called exactly once, and the decision to show warning happens after. Great optimization!

// Always call KYC initiation once
const result = await onInitiateKyc()

// Then decide if warning is needed based on media check
if (result?.success && (!mediaCheck.supported || mediaCheck.severity === 'warning')) {
    // Show warning
}

3. Loading State Added - FIXED

New isChecking state (lines 18, 23-25, 47) prevents double-clicks and provides user feedback during the media check. Both modals now show "Loading..." text (InitiateBridgeKYCModal line 85, InitiateMantecaKYCModal line 94).

4. URL Security Validation - NEW IMPROVEMENT

Added URL validation in handleOpenInBrowser (lines 55-63):

const url = new URL(kycUrlForBrowser)
if (url.protocol === 'https:') {
    window.open(kycUrlForBrowser, '_blank')
}

This prevents opening non-HTTPS URLs. Good security practice!


⚠️ Remaining Issues (Low Priority)

1. useEffect Dependency - Unstable Callback

Severity: LOW 🟡

InitiateMantecaKYCModal.tsx line 75:

useEffect(() => {
    // postMessage listener
}, [onKycSuccess])

Impact: If parent doesn't memoize onKycSuccess, effect re-runs unnecessarily (listener added/removed on every render).

Recommendation: Either:

  • Ask parent to memoize: const onKycSuccess = useCallback(() => { ... }, [deps])
  • Or remove from deps if only needs to run once: useEffect(() => { ... }, [])

The listener doesn't actually use onKycSuccess from closure, so empty deps would work.

2. enumerateDevices() Limitations

Severity: LOW 🟢

As noted before, enumerateDevices() only checks hardware presence, not actual permissions. A camera could be listed but:

  • User denied permission in browser
  • Camera is in use by another app
  • Camera is physically disabled

This is an inherent browser API limitation. The warning modal handles this gracefully by offering "Try Anyway" option, so acceptable.

3. User-Agent Detection Brittleness

Severity: LOW 🟢

mediaPermissions.utils.ts uses regex for in-app browser detection:

const inAppBrowser = /FBAN|FBAV|Instagram|Twitter|Line|WhatsApp/i.test(ua)

New in-app browsers (TikTok, LinkedIn, etc.) won't be detected. But this is a "best effort" warning system, and the "Try Anyway" fallback covers unknowns.

Optional Enhancement: Could add more UA strings over time as you discover new cases.

4. Dark Mode Global Change

Severity: LOW 🟢

The tailwind.config.js and globals.css changes enable dark mode app-wide. This is a design decision rather than a bug, but carries visual regression risk.

Recommendation: QA should test dark mode across multiple pages, not just KYC flow.


📊 Updated Risk Assessment

Category Previous Current Change
Breaking functionality 🔴 HIGH 🟢 LOW FIXED
UX degradation 🟡 MEDIUM 🟢 LOW IMPROVED
Performance impact 🟡 MEDIUM 🟢 LOW IMPROVED
Edge cases 🟡 MEDIUM 🟡 LOW-MEDIUM IMPROVED
Code quality 🟢 LOW 🟢 LOW MAINTAINED

Overall Risk: LOW


🎯 Code Quality Observations

Positive Changes:

  1. Better separation of concerns - isChecking flag prevents race conditions
  2. Security-conscious - HTTPS validation before opening URLs
  3. User experience - Loading states provide clear feedback
  4. DRY principle - Hook abstraction eliminated duplication effectively

Nitpicks (Optional):

  1. Could extract the URL validation logic to a utility function for reuse
  2. The try-finally pattern in handleVerifyClick is clean but could add error logging in catch block for debugging

🧪 Updated QA Testing Guide

Priority Test Scenarios:

1. Happy Path - Normal Device

  • Device: Desktop with webcam
  • Steps:
    1. Click "Verify now"
    2. Should see "Loading..." briefly
    3. Proceeds to KYC iframe (no warning)
  • Expected: < 1 second total, smooth flow

2. No Camera - Error Modal

  • Device: Desktop without camera OR browser permission denied
  • Steps:
    1. Click "Verify now"
    2. "Loading..." → Error modal: "Camera or Microphone Required"
    3. Only "Open in Browser" visible
    4. Click "Open in Browser" → Opens in new HTTPS tab
  • Expected: Modal closes, new tab opens

3. In-App Browser - Warning Modal

  • Device: iPhone in Instagram/Facebook browser
  • Steps:
    1. Click "Verify now"
    2. "Loading..." → Warning modal: "Camera Access May Be Limited"
    3. Two buttons: "Open in Browser" and "Try Anyway"
    4. Test "Try Anyway" → Proceeds to KYC
    5. Test "Open in Browser" → Opens in Safari
  • Expected: Both paths work correctly

4. Double-Click Prevention

  • Device: Any
  • Steps:
    1. Click "Verify now" rapidly 5 times
  • Expected: Only one KYC session initiated, button disabled during check

5. Manteca Flow (Country-Specific)

  • Repeat tests 1-4 for Manteca KYC modal
  • Additional: Test country selection persistence
  • Expected: Same behavior as Bridge KYC

6. Dark Mode Comprehensive

  • Toggle dark mode across:
    • KYC modals
    • Camera warning modal
    • Input fields on other pages
    • Panels and borders throughout app
  • Expected: All text readable, proper contrast, no visual glitches

7. Edge Case - HTTP URL Attack

  • Manual test (dev tools):
    1. Modify kycUrlForBrowser to use http:// instead of https://
    2. Click "Open in Browser"
  • Expected: URL should NOT open (security check blocks it)

8. Regression Testing

  • Verify existing users with completed KYC aren't affected
  • Test KYC flows from different entry points (add money, withdraw, request)
  • Confirm no console errors during normal flow
  • Check analytics/tracking still fires correctly

💡 Final Recommendations

Pre-Merge:

✅ All critical issues resolved - SAFE TO MERGE

Optional Enhancements (Future PR):

  1. Memoize onKycSuccess in parent components to fix useEffect dependency
  2. Add error logging in handleVerifyClick catch block for production debugging
  3. Feature flag dark mode if you want gradual rollout
  4. Add more in-app browser UA strings as you discover them

Monitoring Post-Deploy:

  • Watch for any KYC flow drop-off spikes
  • Monitor console errors related to media permissions
  • Check if "Open in Browser" CTA gets high usage (indicates detection issues)

🎉 Summary

The PR went from HIGH RISKLOW RISK after your fixes. The two critical bugs are resolved, performance is improved with loading states, and security is enhanced with URL validation. The remaining issues are minor and don't block merge.

Recommendation: ✅ APPROVE after successful QA testing

Great refactoring work! The code is now cleaner, safer, and more maintainable. 🚀


🧠 Learnings used
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 852
File: src/hooks/useTransactionHistory.ts:177-239
Timestamp: 2025-05-14T21:16:06.369Z
Learning: When reviewing code, pay attention to and resolve CodeRabbit comments as they can contain useful refactoring suggestions and insights.

Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 594
File: src/components/Request/Pay/Views/Initial.view.tsx:188-213
Timestamp: 2024-12-31T15:08:15.640Z
Learning: Always resolve coderabbit comments when reviewing code, since they can contain useful suggestions.

Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 942
File: src/components/AddMoney/consts/index.ts:2151-2162
Timestamp: 2025-06-30T10:44:08.048Z
Learning: Hugo0 often agrees with refactoring suggestions but defers implementation due to time constraints, preferring to track improvements as follow-up issues when they're part of larger architectural changes.

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: 0

Caution

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

⚠️ Outside diff range comments (1)
src/components/Kyc/InitiateMantecaKYCModal.tsx (1)

57-72: Wrap onKycSuccess callbacks with useCallback in all parent components to prevent unnecessary event listener churn.

The concern is valid and systematic: all 6 call sites pass non-memoized callbacks to MantecaGeoSpecificKycModal, causing the message event listener to be removed and re-added on every parent render.

Affected files require fixes:

  • src/components/Payment/Views/MantecaFulfillment.view.tsx:87–91
  • src/components/AddMoney/components/MantecaAddMoney.tsx:155–159
  • src/components/Profile/views/IdentityVerification.view.tsx:208 (handleRedirect)
  • src/components/Claim/Link/MantecaFlowManager.tsx:136–140
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx:561–565
  • src/app/(mobile-ui)/qr-pay/page.tsx:873–881

Wrap each callback with useCallback to stabilize the dependency and prevent listener churn.

🧹 Nitpick comments (1)
src/components/Kyc/InitiateMantecaKYCModal.tsx (1)

59-60: Origin validation is weak but acceptable.

The origin validation checks if event.origin.includes('manteca'), which is relatively permissive (e.g., would match https://fake-manteca-phishing.com). For stricter security, consider validating against the exact expected origin.

Example of stricter validation:

-if (!event.origin.includes('manteca')) return
+const ALLOWED_ORIGINS = ['https://manteca.example.com', 'https://manteca-staging.example.com']
+if (!ALLOWED_ORIGINS.includes(event.origin)) return

However, if the actual Manteca domain includes "manteca" as a subdomain or path, the current approach may be sufficient for this use case.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a35b9c7 and f8d3695.

📒 Files selected for processing (3)
  • src/components/Kyc/InitiateBridgeKYCModal.tsx (5 hunks)
  • src/components/Kyc/InitiateMantecaKYCModal.tsx (4 hunks)
  • src/hooks/useKycCameraCheck.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 942
File: src/components/AddMoney/consts/index.ts:2151-2162
Timestamp: 2025-06-30T10:44:08.048Z
Learning: Hugo0 often agrees with refactoring suggestions but defers implementation due to time constraints, preferring to track improvements as follow-up issues when they're part of larger architectural changes.
📚 Learning: 2025-08-11T10:35:02.715Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1078
File: src/hooks/useKycFlow.ts:129-141
Timestamp: 2025-08-11T10:35:02.715Z
Learning: In the KYC flow implementation in `src/hooks/useKycFlow.ts`, when Terms of Service (ToS) is accepted, there will always be a KYC link available in the `apiResponse`. The system ensures this invariant, so defensive checks for missing KYC links after ToS acceptance are unnecessary.

Applied to files:

  • src/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateBridgeKYCModal.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/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateBridgeKYCModal.tsx
  • src/components/Kyc/InitiateMantecaKYCModal.tsx
📚 Learning: 2025-06-22T16:10:53.167Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 915
File: src/hooks/useKycFlow.ts:96-124
Timestamp: 2025-06-22T16:10:53.167Z
Learning: The `initiateKyc` function in `src/app/actions/users.ts` already includes comprehensive error handling with try-catch blocks and returns structured responses with either `{ data }` or `{ error }` fields, so additional try-catch blocks around its usage are not needed.

Applied to files:

  • src/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateBridgeKYCModal.tsx
  • src/components/Kyc/InitiateMantecaKYCModal.tsx
📚 Learning: 2025-08-20T09:08:19.266Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1112
File: src/components/Claim/Link/views/BankFlowManager.view.tsx:336-343
Timestamp: 2025-08-20T09:08:19.266Z
Learning: In the KYC flow implementation, `setJustCompletedKyc` must be called after `await fetchUser()` in the `handleKycSuccess` callback. Setting `justCompletedKyc` before fetching the user would cause a re-fetching loop because `handleKycSuccess` is set in a useEffect inside the KYC hook, which would cause the UI flow to get stuck in one view.

Applied to files:

  • src/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateBridgeKYCModal.tsx
  • src/components/Kyc/InitiateMantecaKYCModal.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/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateBridgeKYCModal.tsx
  • src/components/Kyc/InitiateMantecaKYCModal.tsx
📚 Learning: 2024-10-24T12:45:22.708Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 478
File: src/components/Request/Create/Views/Initial.view.tsx:169-176
Timestamp: 2024-10-24T12:45:22.708Z
Learning: When calling `handleOnNext` in `src/components/Request/Create/Views/Initial.view.tsx`, it's acceptable to duplicate parameter lists for readability instead of refactoring to avoid duplication.

Applied to files:

  • src/hooks/useKycCameraCheck.ts
📚 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/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateBridgeKYCModal.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/hooks/useKycCameraCheck.ts
  • src/components/Kyc/InitiateMantecaKYCModal.tsx
📚 Learning: 2025-10-07T10:19:20.077Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1286
File: src/components/MultiStepBankAccountForm/FormInput.tsx:10-10
Timestamp: 2025-10-07T10:19:20.077Z
Learning: The codebase follows a strict policy of avoiding `any` types. Always use proper TypeScript types, particularly from libraries like react-hook-form (RegisterOptions, FieldErrors, UseFormSetValue, etc.) rather than using `any`.

Applied to files:

  • src/hooks/useKycCameraCheck.ts
📚 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/Kyc/InitiateBridgeKYCModal.tsx
  • src/components/Kyc/InitiateMantecaKYCModal.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/Kyc/InitiateBridgeKYCModal.tsx
  • src/components/Kyc/InitiateMantecaKYCModal.tsx
🧬 Code graph analysis (3)
src/hooks/useKycCameraCheck.ts (1)
src/utils/mediaPermissions.utils.ts (2)
  • MediaCheckResult (6-12)
  • checkKycMediaReadiness (103-117)
src/components/Kyc/InitiateBridgeKYCModal.tsx (3)
src/hooks/useKycCameraCheck.ts (1)
  • useKycCameraCheck (14-80)
src/utils/general.utils.ts (1)
  • saveRedirectUrl (786-790)
src/components/Kyc/CameraPermissionWarningModal.tsx (1)
  • CameraPermissionWarningModal (19-79)
src/components/Kyc/InitiateMantecaKYCModal.tsx (2)
src/hooks/useKycCameraCheck.ts (1)
  • useKycCameraCheck (14-80)
src/components/Kyc/CameraPermissionWarningModal.tsx (1)
  • CameraPermissionWarningModal (19-79)
⏰ 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 (4)
src/components/Kyc/InitiateBridgeKYCModal.tsx (1)

37-49: LGTM - Critical issue resolved.

The previous critical issue regarding setShowCameraWarning being undefined has been resolved. The useKycCameraCheck hook now correctly exports setShowCameraWarning (line 73 in useKycCameraCheck.ts), so calling setShowCameraWarning(false) on line 94 is valid and will not cause a runtime error.

The camera check integration is well-implemented with proper loading states and flow control.

Also applies to: 94-94

src/hooks/useKycCameraCheck.ts (2)

20-47: LGTM - Duplicate API call issue resolved.

The previous concern about duplicate onInitiateKyc() calls has been properly addressed. The function now calls onInitiateKyc() exactly once (line 30) and reuses the result throughout the conditional logic. The comment "Always call KYC initiation once" accurately reflects the implementation.

The flow correctly handles the camera warning path and ensures shouldProceed is determined from a single API call.


71-79: LGTM - Exports setShowCameraWarning as needed.

The hook now correctly exports setShowCameraWarning, resolving the critical issue flagged in previous reviews. Consumers of this hook (InitiateBridgeKYCModal and InitiateMantecaKYCModal) can now safely call setShowCameraWarning(false) in their onClose handlers.

src/components/Kyc/InitiateMantecaKYCModal.tsx (1)

44-55: LGTM - Critical issue resolved.

Similar to the Bridge KYC modal, the critical issue with setShowCameraWarning being undefined has been resolved. The useKycCameraCheck hook now exports setShowCameraWarning, making the call on line 104 valid.

The camera check integration follows the same pattern as InitiateBridgeKYCModal and is properly implemented.

Also applies to: 104-104

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: 0

Caution

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

⚠️ Outside diff range comments (1)
src/styles/globals.css (1)

5-9: Inconsistency: color-scheme: light only conflicts with dark-mode enablement.

The AI summary states the aggressive light-mode enforcement block was removed, but Line 7–9 still contains color-scheme: light only within @layer base. If the PR's goal is to enable dark mode (as evidenced by the Tailwind config change and dark: variants added throughout), this rule directly conflicts with it and may prevent dark mode rendering from working properly.

Clarify intent: should this be updated to color-scheme: light dark; or removed entirely to allow the Tailwind dark: classes to function as intended?

🧹 Nitpick comments (1)
src/styles/globals.css (1)

1-432: Visual QA required: dark-mode enablement is a design-level risk.

Per PR objectives, enabling dark mode app-wide (via Tailwind config change and these CSS updates) requires comprehensive visual QA to prevent regressions. Ensure QA covers:

  • All panel, input, border, and ring components in both light and dark modes.
  • Modal and form layouts (especially KYC flows modified in this PR).
  • Color contrast and readability in dark mode.
  • Cross-browser and device testing (especially mobile dark-mode triggers).

Consider feature-flagged rollout or staged QA if regressions are detected.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8d3695 and f53c6dc.

📒 Files selected for processing (1)
  • src/styles/globals.css (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 942
File: src/components/AddMoney/consts/index.ts:2151-2162
Timestamp: 2025-06-30T10:44:08.048Z
Learning: Hugo0 often agrees with refactoring suggestions but defers implementation due to time constraints, preferring to track improvements as follow-up issues when they're part of larger architectural changes.
📚 Learning: 2025-05-21T18:52:22.958Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 870
File: src/styles/globals.css:18-18
Timestamp: 2025-05-21T18:52:22.958Z
Learning: In the peanut-ui project, using `-webkit-tap-highlight-color: none` fixed an issue with blue highlights appearing when tapping inputs on mobile devices, even though `none` is not a technically valid value for this CSS property according to specifications. The valid alternative would be `transparent`.

Applied to files:

  • src/styles/globals.css
⏰ 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 (2)
src/styles/globals.css (2)

393-393: Dark-mode utility classes are properly added and consistent.

The dark: variants added to .panel, .input-text, .border-rounded, and .ring-sm follow Tailwind conventions and are correctly formatted. The duplicate dark:border-white flagged in the past review of .input-text has been resolved.

Also applies to: 419-419, 428-428, 432-432


15-15: Tap-highlight styling uses correct transparent value.

The use of -webkit-tap-highlight-color: transparent; is correct per CSS specs (an improvement from the non-standard none). Placement is redundant across body and button selectors but functionally harmless.

Also applies to: 23-23

@Hugo0 Hugo0 changed the title fix fix: camera & dark mode revert Nov 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant