Skip to content

[TASK-13870] Feat: Add identity verification button in profile page#1169

Merged
Zishan-7 merged 3 commits intopeanut-wallet-devfrom
feat/add-verification-button
Sep 4, 2025
Merged

[TASK-13870] Feat: Add identity verification button in profile page#1169
Zishan-7 merged 3 commits intopeanut-wallet-devfrom
feat/add-verification-button

Conversation

@Zishan-7
Copy link
Copy Markdown
Contributor

@Zishan-7 Zishan-7 commented Sep 2, 2025

No description provided.

@Zishan-7 Zishan-7 requested a review from jjramirezn September 2, 2025 16:57
@notion-workspace
Copy link
Copy Markdown

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Sep 2, 2025

Walkthrough

Adds a Shield SVG icon and registers it in the Icon registry; extends ProfileMenuItem with customizable trailing icon and altered onClick rendering; integrates KYC-aware UI in Profile with a modal and new Identity Verification menu entry; adds IdentityVerification view and mobile route page.

Changes

Cohort / File(s) Summary of changes
Icons: add Shield
src/components/Global/Icons/Icon.tsx, src/components/Global/Icons/shield.tsx
Adds ShieldIcon SVG component and registers "shield" in the IconName union and iconComponents mapping; ShieldIcon is exported and uses currentColor with props spread.
Profile menu item enhancements
src/components/Profile/components/ProfileMenuItem.tsx
Adds optional endIcon?: IconName and endIconClassName?: string props; uses tailwind-merge to compute trailing icon classes; renders a clickable Card directly when onClick is provided instead of wrapping with Link.
Profile KYC integration
src/components/Profile/index.tsx
Introduces isKycApprovedModalOpen state and isKycApproved flag, updates ProfileHeader verified prop, adds an “Identity Verification” ProfileMenuItem that either navigates or opens an approval modal, and renders an ActionModal.
Identity verification view
src/components/Profile/views/IdentityVerification.view.tsx
Adds IdentityVerificationView component: user details form prefilled from auth, updateUser flow, error handling, refresh via fetchUser, KYC initiation, iframe wrapper, and verification-progress modal.
Route: identity verification page
src/app/(mobile-ui)/profile/identity-verification/page.tsx
Adds IdentityVerificationPage that composes IdentityVerificationView inside PageContainer.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • jjramirezn
  • Hugo0

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1b68c01 and 96c0900.

📒 Files selected for processing (1)
  • src/components/Global/Icons/Icon.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Global/Icons/Icon.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
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-verification-button

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@vercel
Copy link
Copy Markdown

vercel bot commented Sep 2, 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 Sep 4, 2025 1:59pm

Copy link
Copy Markdown
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: 7

🧹 Nitpick comments (10)
src/components/Global/Icons/shield.tsx (1)

5-5: Default decorative a11y attributes for SVG icons

Set aria-hidden and focusable defaults so decorative icons aren’t announced. Consumers can still override via props.

-        <svg width="17" height="21" viewBox="0 0 17 21" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
+        <svg
+            width="17"
+            height="21"
+            viewBox="0 0 17 21"
+            fill="none"
+            xmlns="http://www.w3.org/2000/svg"
+            aria-hidden="true"
+            focusable="false"
+            {...props}
+        >
src/components/Global/Icons/Icon.tsx (1)

192-201: Replace fill prop on Icon with className or style.color
We found ~20 instances of <Icon … fill="…"> across multiple components. Migrate these to Tailwind text-color classes (e.g., text-black, text-success-3) or style={{ color }} so icons leveraging currentColor (like ShieldIcon) render correctly.

src/components/Profile/index.tsx (2)

26-26: KYC status check is fine; consider widening if backend enums vary in case

If backend could return 'APPROVED' or similar, normalize before compare to reduce brittleness.

-const isKycApproved = user?.user.kycStatus === 'approved'
+const isKycApproved = (user?.user.kycStatus ?? '').toLowerCase() === 'approved'

44-44: Minor: redundant fallback

fullName already falls back to username; the “|| username” here is redundant.

-<ProfileHeader name={fullName || username} username={username} isVerified={isKycApproved} />
+<ProfileHeader name={fullName} username={username} isVerified={isKycApproved} />
src/components/Profile/components/ProfileMenuItem.tsx (1)

42-47: Trailing icon classes: provide a small default when endIcon is set

If endIcon is provided without endIconClassName, className becomes undefined. Consider a tiny default size for consistency.

- className={twMerge(endIcon ? endIconClassName : 'rotate-90')}
+ className={twMerge(endIcon ? (endIconClassName ?? 'size-4') : 'rotate-90')}
src/components/Profile/views/IdentityVerification.view.tsx (5)

48-49: Trim composed full name before sending to API.

Avoid trailing spaces when last name is empty.

-                fullName: `${data.firstName} ${data.lastName}`,
+                fullName: `${data.firstName} ${data.lastName}`.trim(),

29-31: More robust name parsing from fullName.

Handle extra whitespace and multiple spaces.

-    const [firstName, ...lastNameParts] = (user?.user.fullName ?? '').split(' ')
-    const lastName = lastNameParts.join(' ')
+    const [firstName, ...lastNameParts] = (user?.user.fullName ?? '')
+        .trim()
+        .split(/\s+/)
+        .filter(Boolean)
+    const lastName = lastNameParts.join(' ')

32-39: Reduce redundant useMemo deps.

firstName/lastName derive from fullName; no need to depend on all three.

-        [user?.user.fullName, user?.user.email, firstName, lastName]
+        [user?.user.fullName, user?.user.email]

68-68: Prefer router.back() for back behavior.

Better matches user expectation and preserves history.

-            <NavHeader title="Identity Verification" onPrev={() => router.replace('/profile')} />
+            <NavHeader title="Identity Verification" onPrev={() => router.back()} />

41-64: Type the submit handler’s return for consistency with form.

Makes intent explicit and avoids accidental return shapes.

-    const handleUserDetailsSubmit = async (data: UserDetailsFormData) => {
+    const handleUserDetailsSubmit = async (
+        data: UserDetailsFormData
+    ): Promise<{ error?: string }> => {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 658207d and e3ff145.

📒 Files selected for processing (6)
  • src/app/(mobile-ui)/profile/indentity-verification/page.tsx (1 hunks)
  • src/components/Global/Icons/Icon.tsx (3 hunks)
  • src/components/Global/Icons/shield.tsx (1 hunks)
  • src/components/Profile/components/ProfileMenuItem.tsx (5 hunks)
  • src/components/Profile/index.tsx (5 hunks)
  • src/components/Profile/views/IdentityVerification.view.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
src/components/Profile/index.tsx (1)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/components/Profile/views/IdentityVerification.view.tsx (5)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/hooks/useKycFlow.ts (1)
  • useKycFlow (38-186)
src/components/AddMoney/UserDetailsForm.tsx (2)
  • UserDetailsFormData (7-11)
  • UserDetailsForm (20-113)
src/app/actions/users.ts (1)
  • updateUserById (12-35)
src/components/Kyc/KycVerificationInProgressModal.tsx (1)
  • KycVerificationInProgressModal (12-54)
src/components/Global/Icons/Icon.tsx (1)
src/components/Global/Icons/shield.tsx (1)
  • ShieldIcon (3-16)
src/components/Profile/components/ProfileMenuItem.tsx (1)
src/components/Global/Icons/Icon.tsx (2)
  • IconName (63-122)
  • Icon (192-201)
⏰ 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 (6)
src/components/Global/Icons/Icon.tsx (1)

60-60: LGTM: Shield icon wired into the icon registry

Import, union type, and mapping look correct. No runtime concerns.

Also applies to: 122-122, 189-190

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

11-12: LGTM: Modal deps imported

Imports for ActionModal and useState are fine.


16-16: LGTM: Local modal state

State wiring is straightforward.


115-129: LGTM: “Already verified” modal UX

Clear message and single CTA works. Consider adding analytics event on open/close if you track KYC funnels.

src/components/Profile/components/ProfileMenuItem.tsx (2)

6-6: LGTM: Using tailwind-merge for dynamic icon classes

Solid choice to avoid class conflicts.


16-18: LGTM: endIcon API

New props are minimal and useful for trailing indicators.

Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
src/components/Profile/views/IdentityVerification.view.tsx (1)

1-3: Server-only import inside a client component (will break at build/hydration).
updateUserById from app/actions/users uses cookies() (server-only). Importing it in a "use client" component will fail in Next.js.

Apply this diff to switch to a client-safe wrapper (ensure the wrapper exists):

 'use client'
-import { updateUserById } from '@/app/actions/users'
+import { updateUserById } from '@/lib/client/users'

I can add the minimal client helper and API route if you want me to push a follow-up patch.

🧹 Nitpick comments (2)
src/components/Profile/views/IdentityVerification.view.tsx (2)

21-29: Refresh user on KYC approval via hook callback.
Pass onKycSuccess to useKycFlow to fetch fresh user data when status flips to approved.

-    } = useKycFlow()
+    } = useKycFlow({
+        onKycSuccess: async () => {
+            await fetchUser()
+        },
+    })

31-41: Normalize name parsing and simplify memo dependencies.
Trim/collapse whitespace and compute first/last inside the memo; reduces re-computation and handles edge cases (single names, extra spaces).

-    const [firstName, ...lastNameParts] = (user?.user.fullName ?? '').split(' ')
-    const lastName = lastNameParts.join(' ')
-
-    const initialUserDetails: Partial<UserDetailsFormData> = useMemo(
-        () => ({
-            firstName: user?.user.fullName ? firstName : '',
-            lastName: user?.user.fullName ? lastName : '',
-            email: user?.user.email ?? '',
-        }),
-        [user?.user.fullName, user?.user.email, firstName, lastName]
-    )
+    const initialUserDetails: Partial<UserDetailsFormData> = useMemo(() => {
+        const fullName = (user?.user.fullName ?? '').trim()
+        const [first, ...rest] = fullName ? fullName.split(/\s+/) : ['', '']
+        return {
+            firstName: first || '',
+            lastName: rest.join(' ') || '',
+            email: user?.user.email ?? '',
+        }
+    }, [user?.user.fullName, user?.user.email])
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e3ff145 and 1b68c01.

📒 Files selected for processing (3)
  • src/app/(mobile-ui)/profile/identity-verification/page.tsx (1 hunks)
  • src/components/Profile/index.tsx (5 hunks)
  • src/components/Profile/views/IdentityVerification.view.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Profile/index.tsx
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-08-20T09:08:19.266Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#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/components/Profile/views/IdentityVerification.view.tsx
📚 Learning: 2025-06-22T16:10:53.167Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#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/components/Profile/views/IdentityVerification.view.tsx
📚 Learning: 2025-08-11T10:35:02.715Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#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/components/Profile/views/IdentityVerification.view.tsx
🧬 Code graph analysis (1)
src/components/Profile/views/IdentityVerification.view.tsx (6)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/hooks/useKycFlow.ts (1)
  • useKycFlow (38-186)
src/components/AddMoney/UserDetailsForm.tsx (2)
  • UserDetailsFormData (7-11)
  • UserDetailsForm (20-113)
src/app/actions/users.ts (1)
  • updateUserById (12-35)
src/components/0_Bruddle/Button.tsx (1)
  • Button (76-267)
src/components/Kyc/KycVerificationInProgressModal.tsx (1)
  • KycVerificationInProgressModal (12-54)
⏰ 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 (3)
src/app/(mobile-ui)/profile/identity-verification/page.tsx (1)

4-10: LGTM: page wires the view inside PageContainer correctly.
Straightforward server page rendering a client view; no issues spotted.

src/components/Profile/views/IdentityVerification.view.tsx (2)

81-89: Good guardrails on CTA (prevents double actions).
Button correctly reflects isUpdatingUser || isKycLoading for loading/disabled states.


93-93: User-facing errors surfaced properly.
Combining userUpdateError and kycError ensures visibility of both failure modes.

@jjramirezn
Copy link
Copy Markdown
Contributor

Wait for prod release before merging

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