Skip to content

Conversation

Hugo0
Copy link
Contributor

@Hugo0 Hugo0 commented Jun 3, 2025

No description provided.

Copy link

vercel bot commented Jun 3, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
peanut-ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 3, 2025 8:40am

Copy link
Contributor

coderabbitai bot commented Jun 3, 2025

Walkthrough

This change refactors avatar color logic across multiple components to use light and dark shades from a new color mapping utility, updates transaction detail components by splitting the drawer and receipt logic, integrates Google Tag Manager, restricts username validation to exclude underscores, and adds total sent/received stats to public user profiles with corresponding API changes.

Changes

Files/Groups Change Summary
src/utils/color.utils.ts Refactored color mapping to provide lightShade/darkShade per color; updated getColorForUsername to return both shades; changed AVATAR_LINK_BG and AVATAR_WALLET_BG assignments.
src/components/Profile/AvatarWithBadge.tsx
src/components/User/UserCard.tsx
src/components/AddWithdraw/components/AddWithdrawCountriesList.tsx
src/components/Global/PeanutActionDetailsCard/index.tsx
src/components/TransactionDetails/TransactionAvatarBadge.tsx
Updated avatar background and text color logic to use lightShade and darkShade from getColorForUsername; added/adjusted conditional logic for recipient types and transaction types.
src/components/TransactionDetails/TransactionDetailsDrawer.tsx Refactored: split receipt rendering into TransactionDetailsReceipt; added dynamic drawer height; improved loading state management and clarified conditional rendering for transaction states; updated cancellation logic and button labels.
src/app/[...recipient]/client.tsx
src/components/Claim/Claim.tsx
Replaced TransactionDetailsDrawer with TransactionDetailsReceipt; updated user role and username fallback logic in transaction detail rendering.
src/app/layout.tsx Added Google Tag Manager integration via next/script and noscript fallback.
src/components/Profile/components/PublicProfile.tsx
src/services/users.ts
Added totalUsdSent and totalUsdReceived to user API and public profile display; fetched and displayed these values in PublicProfile component.
src/components/Setup/Views/Signup.tsx Updated username validation regex to disallow underscores; revised error messaging accordingly.
src/app/(mobile-ui)/history/layout.tsx Changed page metadata title from "Transaction History
src/components/Global/TokenSelector/TokenSelector.tsx Removed assignment of buttonChainLogoURI from chainInfo.chainIconURI for external wallet and selected token.
src/hooks/useTransactionHistory.ts Added construction of link URL for DIRECT_SEND transaction entries.

Possibly related PRs

  • peanutprotocol/peanut-ui#883: Also modifies PublicProfile.tsx and users.ts to add and use totalUsdSent and totalUsdReceived for displaying transaction stats.
  • peanutprotocol/peanut-ui#882: Updates avatar color styling logic to use lightShade and darkShade variants from getColorForUsername, similar to this PR's color refactor.
  • peanutprotocol/peanut-ui#885: Refactors transaction detail components, replacing TransactionDetailsDrawer with TransactionDetailsReceipt and updating related rendering logic.

Suggested reviewers

  • jjramirezn
  • kushagrasarathe
✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai 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

Documentation and Community

  • 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.

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

🧹 Nitpick comments (1)
src/components/TransactionDetails/TransactionDetailsDrawer.tsx (1)

225-235: Remove unnecessary fragment.

The fragment only contains a single conditional block and can be simplified.

Apply this diff to remove the unnecessary fragment:

-{transaction.status === 'cancelled' &&
-    transaction.extraDataForDrawer?.originalUserRole === EHistoryUserRole.BOTH &&
-    transaction.cancelledDate && (
-        <>
-            {transaction.cancelledDate && (
-                <PaymentInfoRow
-                    label="Cancelled"
-                    value={formatDate(transaction.cancelledDate as Date)}
-                    hideBottomBorder={
-                        !transaction.fee && !transaction.memo && !transaction.attachmentUrl
-                    }
-                />
-            )}
-        </>
-    )}
+{transaction.status === 'cancelled' &&
+    transaction.extraDataForDrawer?.originalUserRole === EHistoryUserRole.BOTH &&
+    transaction.cancelledDate && (
+        <PaymentInfoRow
+            label="Cancelled"
+            value={formatDate(transaction.cancelledDate as Date)}
+            hideBottomBorder={
+                !transaction.fee && !transaction.memo && !transaction.attachmentUrl
+            }
+        />
+    )}
🧰 Tools
🪛 Biome (1.9.4)

[error] 225-235: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a9c6afe and 552f0a2.

📒 Files selected for processing (16)
  • src/app/(mobile-ui)/history/layout.tsx (1 hunks)
  • src/app/[...recipient]/client.tsx (4 hunks)
  • src/app/layout.tsx (2 hunks)
  • src/components/AddWithdraw/components/AddWithdrawCountriesList.tsx (1 hunks)
  • src/components/Claim/Claim.tsx (2 hunks)
  • src/components/Global/PeanutActionDetailsCard/index.tsx (2 hunks)
  • src/components/Global/TokenSelector/TokenSelector.tsx (0 hunks)
  • src/components/Profile/AvatarWithBadge.tsx (1 hunks)
  • src/components/Profile/components/PublicProfile.tsx (4 hunks)
  • src/components/Setup/Views/Signup.tsx (1 hunks)
  • src/components/TransactionDetails/TransactionAvatarBadge.tsx (1 hunks)
  • src/components/TransactionDetails/TransactionDetailsDrawer.tsx (5 hunks)
  • src/components/User/UserCard.tsx (2 hunks)
  • src/hooks/useTransactionHistory.ts (1 hunks)
  • src/services/users.ts (3 hunks)
  • src/utils/color.utils.ts (3 hunks)
💤 Files with no reviewable changes (1)
  • src/components/Global/TokenSelector/TokenSelector.tsx
🧰 Additional context used
🧬 Code Graph Analysis (9)
src/components/AddWithdraw/components/AddWithdrawCountriesList.tsx (2)
src/utils/color.utils.ts (1)
  • getColorForUsername (51-69)
src/components/Global/Icons/Icon.tsx (1)
  • IconName (51-98)
src/components/Profile/AvatarWithBadge.tsx (1)
src/utils/color.utils.ts (1)
  • getColorForUsername (51-69)
src/components/Claim/Claim.tsx (1)
src/components/TransactionDetails/TransactionDetailsDrawer.tsx (1)
  • TransactionDetailsReceipt (80-445)
src/hooks/useTransactionHistory.ts (1)
src/constants/general.consts.ts (1)
  • BASE_URL (43-43)
src/app/[...recipient]/client.tsx (1)
src/components/TransactionDetails/TransactionDetailsDrawer.tsx (1)
  • TransactionDetailsReceipt (80-445)
src/services/users.ts (2)
src/utils/sentry.utils.ts (1)
  • fetchWithSentry (11-89)
src/constants/general.consts.ts (1)
  • PEANUT_API_URL (37-41)
src/components/User/UserCard.tsx (1)
src/utils/color.utils.ts (2)
  • getColorForUsername (51-69)
  • AVATAR_TEXT_DARK (44-44)
src/components/Profile/components/PublicProfile.tsx (2)
src/context/authContext.tsx (1)
  • useAuth (198-204)
src/utils/general.utils.ts (1)
  • formatExtendedNumber (997-1045)
src/components/Global/PeanutActionDetailsCard/index.tsx (1)
src/utils/color.utils.ts (2)
  • getColorForUsername (51-69)
  • AVATAR_TEXT_DARK (44-44)
🪛 Biome (1.9.4)
src/components/TransactionDetails/TransactionDetailsDrawer.tsx

[error] 225-235: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Deploy-Preview
🔇 Additional comments (20)
src/utils/color.utils.ts (3)

6-35: Well-structured color mapping refactor.

The refactoring from single hex strings to objects with lightShade and darkShade properties provides better flexibility for dual-shade color schemes across the application.


38-39:

❓ Verification inconclusive

Verify the hardcoded color value matches the intended design.

The AVATAR_LINK_BG was changed from COLORS_MAPPING.peanut_pink to a hardcoded value '#FF90E8'. Ensure this hardcoded value aligns with the design system and consider using COLORS_MAPPING.peanut_pink.lightShade or darkShade for consistency.


🏁 Script executed:

#!/bin/bash
# Description: Verify if the hardcoded color value matches any shade in the peanut_pink mapping
echo "Hardcoded AVATAR_LINK_BG: #FF90E8"
echo "Peanut pink lightShade: #FFD5F6"
echo "Peanut pink darkShade: #FF74E2"
echo "The hardcoded value doesn't match either shade - verify this is intentional"

Length of output: 384


🏁 Script executed:

#!/bin/bash
# Locate where peanut_pink is defined in the repository
FILES=$(rg --files-with-match "peanut_pink" -g "*.ts")
echo "Files containing 'peanut_pink':"
echo "$FILES"

for f in $FILES; do
  echo -e "\n--- File: $f ---"
  rg -n "peanut_pink" -n -A 5 "$f"
done

Length of output: 602


🏁 Script executed:

#!/bin/bash
# Extract the peanut_pink mapping from color.utils.ts
rg -n "peanut_pink" -A5 -B5 src/utils/color.utils.ts

Length of output: 472


Verify peanut pink shade consistency

It looks like AVATAR_LINK_BG was changed to a hardcoded #FF90E8, but your COLORS_MAPPING.peanut_pink only defines:

  • lightShade: #FFD5F6
  • darkShade: #FF74E2

#FF90E8 doesn’t match either. Please confirm one of the following:

  • Was #FF90E8 intentionally chosen as a custom mid-tone? If so, should we add it to COLORS_MAPPING.peanut_pink (e.g. mediumShade) for consistency?
  • Or would it be better to switch back to COLORS_MAPPING.peanut_pink.lightShade or darkShade?

Let me know which approach aligns with the design system.


51-69:

✅ Verification successful

Breaking change: Function signature updated correctly.

The function signature change is implemented correctly and provides better flexibility. However, this is a breaking change that requires updates in all consuming components.


🏁 Script executed:

#!/bin/bash
# Description: Verify all usages of getColorForUsername have been updated to use the new return structure
echo "Searching for getColorForUsername usage patterns..."

# Search for direct usage of the function
rg -A 3 -B 1 "getColorForUsername" --type ts --type tsx

# Search for potential old usage patterns like .backgroundColor
rg "\.backgroundColor" --type ts --type tsx

Length of output: 270


🏁 Script executed:

#!/bin/bash
# Re-run usage search without file-type filters
echo "🔍 Searching for all calls to getColorForUsername..."
rg -n "getColorForUsername\(" .

echo
echo "🔍 Searching for any legacy style props (e.g., .backgroundColor) that might still reference the old return value..."
rg -n "\.backgroundColor" .

Length of output: 1867


All getColorForUsername call sites now use the new return structure
I’ve verified every invocation either destructures or accesses .lightShade/.darkShade, and there are no remaining legacy patterns (e.g. .backgroundColor). No further changes required.

src/app/(mobile-ui)/history/layout.tsx (1)

6-6: Improved page title for better UX.

The shortened title "History | Peanut" is more concise and mobile-friendly compared to the previous "Transaction History | Peanut".

src/hooks/useTransactionHistory.ts (1)

169-173: Consistent link construction for DIRECT_SEND transactions.

The link construction follows the same pattern as the 'REQUEST' case, using username with fallback to identifier and including the transaction UUID as chargeId. This provides consistent URL generation across transaction types.

src/components/Setup/Views/Signup.tsx (1)

41-44:

❓ Verification inconclusive

Breaking change: Underscore restriction in usernames.

The validation regex now excludes underscores from usernames, allowing only lowercase letters and numbers. While the implementation is correct, this is a breaking change that could affect existing users.

Verify the following:

  1. Is this restriction intentional for new usernames only, or should existing usernames with underscores be handled?
  2. Are there any existing users with underscores in their usernames that need migration?

🏁 Script executed:

#!/bin/bash
# Description: Check for existing usage patterns and validate the regex change
echo "Checking for any references to underscore in username validation..."

# Search for other username validation patterns
rg "username.*_" --type ts --type tsx

# Search for any hardcoded usernames with underscores in tests or examples
rg "[a-z]+_[a-z0-9]+" --type ts --type tsx

Length of output: 285


To ensure we catch patterns in both .ts and .tsx files, let’s re-run the search using file globs instead of relying on ripgrep’s built-in types:


🏁 Script executed:

#!/bin/bash
echo "Searching for username validation patterns in .ts and .tsx files..."
rg 'username.*_' -g '*.ts' -g '*.tsx'

echo "Searching for hardcoded usernames with underscores in .ts and .tsx files..."
rg '[a-z]+_[a-z0-9]+' -g '*.ts' -g '*.tsx'

Length of output: 40867


Verify underscore restriction impact

We updated the regex in src/components/Setup/Views/Signup.tsx (lines 41–44) to /^[a-z][a-z0-9]{3,11}$/, removing underscore support for usernames. A code-wide search found no other validation patterns or hardcoded examples that rely on underscores in usernames.

Please confirm:

  • Are there existing user accounts in production that include underscores?
  • Should legacy usernames with underscores be migrated or allowed until users update them?
  • Does Product/QA intend this restriction only for new registrations, or should it apply retroactively?

Once confirmed, update tests or migration scripts as needed.

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

83-84: LGTM! Proper implementation of the new color scheme.

The changes correctly implement the new dual-shade color pattern, using lightShade for background and darkShade for text color. This ensures good contrast and consistency with other avatar components in the codebase.

src/components/Profile/AvatarWithBadge.tsx (1)

73-75: LGTM! Comprehensive implementation of the new color scheme.

The styling logic correctly implements the new dual-shade color pattern with proper fallbacks:

  • Uses lightShade for background when a name is provided
  • Adds darkShade border for definition when name exists without an icon
  • Uses darkShade for text color when name exists, with proper fallback to textColor

This ensures good visual contrast and consistency across different avatar states.

src/services/users.ts (1)

28-29: LGTM! New user statistics fields are properly typed.

The addition of totalUsdSent and totalUsdReceived fields to the ApiUser type is correctly implemented and will support the new statistics display functionality.

src/app/layout.tsx (3)

8-8: LGTM! Proper import for GTM integration.

Good practice to use Next.js Script component for third-party scripts.


62-72: GTM script implementation looks correct.

The implementation follows Google Tag Manager best practices:

  • Using strategy="afterInteractive" for optimal performance
  • Standard GTM initialization code
  • Container ID format is valid

76-83: Good accessibility practice with noscript fallback.

The noscript iframe ensures GTM tracking works even when JavaScript is disabled.

src/components/User/UserCard.tsx (2)

2-2: LGTM! Proper import for new color constants.

Good addition of the AVATAR_TEXT_DARK constant for consistent text coloring.


54-60: Color logic correctly updated for new API.

The changes properly implement the new color utility structure:

  • Using lightShade for background provides appropriate contrast
  • Using AVATAR_TEXT_DARK and darkShade for text ensures readability
  • Logic correctly differentiates between USERNAME and non-USERNAME recipients
src/components/Global/PeanutActionDetailsCard/index.tsx (2)

5-5: LGTM! Proper import for color constant.

Addition of AVATAR_TEXT_DARK import aligns with the color utility refactoring.


93-100: Color text logic includes ENS recipient type correctly.

Good addition of ENS recipient type to the conditional logic. However, verify that using darkShade for both background (line 92) and text color won't create contrast issues.

src/components/Claim/Claim.tsx (2)

3-21: Import reorganization looks good.

The consolidation and addition of new imports aligns with the component refactoring. Good practice to organize related imports together.


278-278: Component refactoring correctly implemented.

The change from TransactionDetailsDrawer to TransactionDetailsReceipt aligns with the component restructuring mentioned in the summary. This simplifies the component by using the extracted receipt logic directly.

src/app/[...recipient]/client.tsx (1)

258-262: Good improvement to username resolution robustness!

The fallback chain from user.usernameidentifierrecipientAddress ensures a username is always available for display, making the code more resilient to different data scenarios.

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

426-426: Good UX improvement with clearer action label!

Changing from "Cancel request" to "Reject request" better communicates the action from the recipient's perspective.

Comment on lines +64 to +65
: getColorForUsername(method.title).lightShade,
color: method.icon === ('bank' as IconName) ? 'black' : 'black',
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix redundant conditional and align with color scheme pattern.

The conditional logic on line 65 is redundant since both branches return 'black'. Based on the new color utility pattern used in other components, non-bank icons should use darkShade for better contrast and consistency.

Apply this diff to fix the redundant conditional:

                                            backgroundColor:
                                                method.icon === ('bank' as IconName)
                                                    ? '#FFC900'
                                                    : getColorForUsername(method.title).lightShade,
-                                            color: method.icon === ('bank' as IconName) ? 'black' : 'black',
+                                            color: method.icon === ('bank' as IconName) ? 'black' : getColorForUsername(method.title).darkShade,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
: getColorForUsername(method.title).lightShade,
color: method.icon === ('bank' as IconName) ? 'black' : 'black',
backgroundColor:
method.icon === ('bank' as IconName)
? '#FFC900'
: getColorForUsername(method.title).lightShade,
color: method.icon === ('bank' as IconName)
? 'black'
: getColorForUsername(method.title).darkShade,
🤖 Prompt for AI Agents
In src/components/AddWithdraw/components/AddWithdrawCountriesList.tsx around
lines 64 to 65, the conditional setting the color to 'black' regardless of the
condition is redundant. Remove the ternary operator and set the color to 'black'
directly for bank icons, and for non-bank icons, use
getColorForUsername(method.title).darkShade to align with the color scheme
pattern used in other components.

Comment on lines +38 to +43
const response = await fetchWithSentry(`${PEANUT_API_URL}/users/username/${username}`, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${Cookies.get('jwt-token')}`,
},
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add defensive handling for missing JWT token.

The authentication implementation correctly adds the Bearer token from cookies, but should handle cases where the token doesn't exist to prevent sending Bearer undefined in the Authorization header.

Apply this diff to add defensive token handling:

    getByUsername: async (username: string): Promise<ApiUser> => {
+        const token = Cookies.get('jwt-token')
+        const headers: Record<string, string> = {
+            'Content-Type': 'application/json',
+        }
+        
+        if (token) {
+            headers.Authorization = `Bearer ${token}`
+        }
+
        const response = await fetchWithSentry(`${PEANUT_API_URL}/users/username/${username}`, {
-            headers: {
-                'Content-Type': 'application/json',
-                Authorization: `Bearer ${Cookies.get('jwt-token')}`,
-            },
+            headers,
        })
        return await response.json()
    },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const response = await fetchWithSentry(`${PEANUT_API_URL}/users/username/${username}`, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${Cookies.get('jwt-token')}`,
},
})
getByUsername: async (username: string): Promise<ApiUser> => {
const token = Cookies.get('jwt-token')
const headers: Record<string, string> = {
'Content-Type': 'application/json',
}
if (token) {
headers.Authorization = `Bearer ${token}`
}
const response = await fetchWithSentry(
`${PEANUT_API_URL}/users/username/${username}`,
{ headers }
)
return await response.json()
},
🤖 Prompt for AI Agents
In src/services/users.ts around lines 38 to 43, the Authorization header
includes a JWT token from cookies without checking if it exists, which can
result in sending 'Bearer undefined'. Fix this by first retrieving the token
from cookies, then conditionally adding the Authorization header only if the
token is present, ensuring no invalid header is sent.

Comment on lines +88 to +92
: transactionType === 'ADD_MONEY' ||
recipientType === 'ADDRESS' ||
recipientType === 'ENS'
? '#FFC900'
: getColorForUsername(recipientName).backgroundColor,
: getColorForUsername(recipientName).darkShade,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix potential contrast issue with background color.

The logic uses darkShade for backgroundColor, but this could create contrast issues since darkShade is also used for text color in line 100. Based on the pattern in other components (like UserCard.tsx), the background should use lightShade instead.

Apply this fix:

-                                  : getColorForUsername(recipientName).darkShade,
+                                  : getColorForUsername(recipientName).lightShade,
🤖 Prompt for AI Agents
In src/components/Global/PeanutActionDetailsCard/index.tsx around lines 88 to
92, the background color uses getColorForUsername(recipientName).darkShade,
which may cause contrast issues since darkShade is also used for text color.
Change the background color to use getColorForUsername(recipientName).lightShade
instead to ensure better contrast and readability, following the pattern used in
similar components like UserCard.tsx.

{/*
<div className="space-y-6">
{!!hasTransactions && (
{totalSent !== '0.00' && totalReceived !== '0.00' && (
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider showing stats when either value is non-zero.

The current condition requires both totalSent AND totalReceived to be non-zero. Users who have only sent or only received money won't see any statistics.

Consider changing the logic to show stats when at least one value is non-zero:

-{totalSent !== '0.00' && totalReceived !== '0.00' && (
+{(totalSent !== '0.00' || totalReceived !== '0.00') && (
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{totalSent !== '0.00' && totalReceived !== '0.00' && (
{(totalSent !== '0.00' || totalReceived !== '0.00') && (
🤖 Prompt for AI Agents
In src/components/Profile/components/PublicProfile.tsx at line 103, the
condition currently requires both totalSent and totalReceived to be non-zero to
display stats. Change the condition to use a logical OR instead of AND so that
stats are shown when either totalSent or totalReceived is non-zero, ensuring
users who have only sent or only received money see their statistics.

Comment on lines +52 to +53
setTotalSent(user.totalUsdSent)
setTotalReceived(user.totalUsdReceived)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null/undefined checks for API response fields.

The code directly assigns user.totalUsdSent and user.totalUsdReceived without checking if these fields exist. This could set undefined values to state if the API doesn't return these fields.

Apply this diff to add proper null checking:

-setTotalSent(user.totalUsdSent)
-setTotalReceived(user.totalUsdReceived)
+setTotalSent(user.totalUsdSent ?? '0.00')
+setTotalReceived(user.totalUsdReceived ?? '0.00')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
setTotalSent(user.totalUsdSent)
setTotalReceived(user.totalUsdReceived)
setTotalSent(user.totalUsdSent ?? '0.00')
setTotalReceived(user.totalUsdReceived ?? '0.00')
🤖 Prompt for AI Agents
In src/components/Profile/components/PublicProfile.tsx around lines 52 to 53,
the code sets state values directly from user.totalUsdSent and
user.totalUsdReceived without checking if these fields are null or undefined. To
fix this, add null or undefined checks before setting the state, for example by
using conditional (ternary) operators or logical OR to provide default values
like 0 when these fields are missing from the API response.

Comment on lines +311 to +323
// Claiming takes time, so we need to invalidate both transaction query types
setTimeout(() => {
fetchBalance()
queryClient
.invalidateQueries({
queryKey: [TRANSACTIONS],
})
.then(() => {
setIsLoading(false)
onClose()
})
}, 3000)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Replace hardcoded timeout with proper completion handling.

Using a fixed 3-second delay for query invalidation is unreliable and could lead to race conditions. The UI might update before the operation actually completes, or users might wait unnecessarily.

Consider implementing a polling mechanism or waiting for actual confirmation:

-.then(() => {
-    // Claiming takes time, so we need to invalidate both transaction query types
-    setTimeout(() => {
-        fetchBalance()
-        queryClient
-            .invalidateQueries({
-                queryKey: [TRANSACTIONS],
-            })
-            .then(() => {
-                setIsLoading(false)
-                onClose()
-            })
-    }, 3000)
-})
+.then(async () => {
+    // Poll for completion or wait for confirmation
+    await fetchBalance()
+    await queryClient.invalidateQueries({
+        queryKey: [TRANSACTIONS],
+    })
+    setIsLoading(false)
+    onClose()
+})

Alternatively, implement a polling mechanism to check the actual status of the claim operation.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Claiming takes time, so we need to invalidate both transaction query types
setTimeout(() => {
fetchBalance()
queryClient
.invalidateQueries({
queryKey: [TRANSACTIONS],
})
.then(() => {
setIsLoading(false)
onClose()
})
}, 3000)
})
.then(async () => {
// Poll for completion or wait for confirmation
await fetchBalance()
await queryClient.invalidateQueries({
queryKey: [TRANSACTIONS],
})
setIsLoading(false)
onClose()
})
🤖 Prompt for AI Agents
In src/components/TransactionDetails/TransactionDetailsDrawer.tsx around lines
311 to 323, replace the hardcoded 3-second setTimeout delay used before
invalidating queries and updating the UI with a more reliable approach. Instead
of waiting a fixed time, implement a polling mechanism or listen for an event
that confirms the claim operation has completed. Once confirmed, invalidate the
queries and update the UI by setting isLoading to false and calling onClose.
This ensures the UI reflects the actual operation status without race conditions
or unnecessary delays.

@Hugo0 Hugo0 closed this Jul 3, 2025
@Hugo0 Hugo0 deleted the chore/gtag branch July 3, 2025 18:28
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.

3 participants