Skip to content

chore: Add additional data to already claimed links and already paid requests#441

Merged
jjramirezn merged 11 commits intodevelopfrom
fix/link-receipts
Oct 16, 2024
Merged

chore: Add additional data to already claimed links and already paid requests#441
jjramirezn merged 11 commits intodevelopfrom
fix/link-receipts

Conversation

@panosfilianos
Copy link
Contributor

@panosfilianos panosfilianos commented Oct 15, 2024

Previously, the claimed link view and already paid request link view did not include all data available. This resulted in poorer UX. This PR:

  • Adds extra data in Claimed Link View
  • Adds extra data in Already Paid Request Link View
  • Changes tab titles to be more specific in both views

@vercel
Copy link

vercel bot commented Oct 15, 2024

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 Oct 16, 2024 2:31pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 15, 2024

📝 Walkthrough

Walkthrough

This pull request introduces several changes across multiple files. A new asynchronous POST function is added to handle incoming requests and interact with an external API for link information. Modifications to metadata titles and enhancements to components improve user feedback and information presentation. Additionally, a utility function for validating bank accounts is introduced, alongside updates to existing components to enhance their interactivity and detail in displaying claimed and paid link information.

Changes

File Path Change Summary
src/app/api/peanut/get-link-info/route.ts Added async function POST(request: NextRequest) to handle POST requests and interact with an API.
src/app/claim/page.tsx Enhanced generateMetadata function to set the title based on claimed status of linkDetails.
src/app/request/pay/page.tsx Updated metadata title from "Peanut Protocol" to "Peanut Protocol - Payment Request."
src/components/Claim/Generic/AlreadyClaimed.view.tsx Modified AlreadyClaimedLinkView to include new imports and conditional rendering for claimed links.
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx Enhanced AlreadyPaidLinkView to display detailed information about previously paid links.
src/utils/link.utils.ts Added async function get(bankAccount: string): Promise<boolean> for bank account validation.

Possibly related PRs

  • Handle link cancel #384: The main PR introduces a new asynchronous function for handling POST requests related to link information, which may relate to the functionality of removing links from local storage in the retrieved PR that handles link cancellation.
  • fix: fixes and refactor in request #422: This PR enhances error handling and control flow in the Request Pay view, which could be relevant to the changes made in the main PR that involve handling responses from an external API.
  • fix(request): recalculate route request pay #433: The modifications in this PR focus on improving error handling and loading states in the Initial view, which aligns with the main PR's emphasis on managing API responses and error logging.
  • fix(request): correctly identify native tokens #434: This PR addresses issues with identifying native tokens, which may connect to the main PR's handling of link information and API interactions.
  • fix(request): store correct destination hash for xchain #437: The changes in this PR streamline transaction handling logic, which could relate to the main PR's focus on managing API responses and error handling.
  • fix: request pay issues #443: This PR addresses various issues related to request pay functionality, which may connect to the main PR's enhancements in handling POST requests and API interactions.

Suggested reviewers

  • Hugo0

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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

🧹 Outside diff range and nitpick comments (3)
src/utils/link.utils.ts (1)

1-3: Address the TODO comment for code organization

The TODO comment indicates that there are link-related utility functions in general.utils.ts that should be moved to this file. It's a good practice to keep related utilities together for better code organization and maintainability.

Consider creating a separate task to move the link-related utilities from general.utils.ts to this file. This will help in better organizing the codebase and make it easier to maintain in the future. Would you like me to create a GitHub issue for this task?

src/app/request/pay/page.tsx (2)

6-7: Good catch on dynamic metadata. Consider creating a task.

The TODO comment about making the metadata dynamic based on payment status is a valuable suggestion. It would indeed improve the user experience by providing more accurate information.

Would you like me to create a GitHub issue to track this enhancement? This would ensure it's not forgotten and can be prioritized appropriately.


8-8: Approved: More descriptive title. Consider further specificity.

The updated title "Peanut Protocol - Payment Request" is more informative and aligns well with the page's purpose. Good job on improving clarity for users.

For even more clarity, consider making it action-oriented, e.g., "Peanut Protocol - Submit Payment Request". This could further help users understand the page's function at a glance.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between faba058 and f6b52c3.

📒 Files selected for processing (6)
  • src/app/api/peanut/get-link-info/route.ts (1 hunks)
  • src/app/claim/page.tsx (1 hunks)
  • src/app/request/pay/page.tsx (1 hunks)
  • src/components/Claim/Generic/AlreadyClaimed.view.tsx (1 hunks)
  • src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (1 hunks)
  • src/utils/link.utils.ts (1 hunks)
🧰 Additional context used
📓 Learnings (1)
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (3)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-08T20:13:42.967Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-03T17:43:19.914Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-08T20:13:44.480Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.
🪛 Biome
src/components/Claim/Generic/AlreadyClaimed.view.tsx

[error] 15-15: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx

[error] 11-11: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (4)
src/app/api/peanut/get-link-info/route.ts (1)

1-4: LGTM: Imports and setup are appropriate.

The imports are correctly set up for a Next.js API route, and the use of a constants file is a good practice for maintainability.

src/app/claim/page.tsx (2)

40-50: 🛠️ Refactor suggestion

Improve readability and handling of token amounts in title construction

The new logic for constructing the title provides more informative feedback to users, which is great. However, consider the following improvements:

  1. Use template literals instead of string concatenation for better readability.
  2. Consider using a more precise method to handle small token amounts, as the current approach might not be suitable for all token types.
  3. Improve the indentation of the multi-line string construction.

Here's a suggested refactor:

if (!linkDetails.claimed) {
    const formattedAmount = Number(linkDetails.tokenAmount) < 0.01
        ? 'a small amount of'
        : utils.formatAmount(Number(linkDetails.tokenAmount));
    title = `You received ${formattedAmount} ${linkDetails.tokenSymbol}!`;
} else {
    title = 'This link has been claimed';
}

This refactored version:

  • Uses template literals for better readability.
  • Separates the amount formatting logic for clarity.
  • Uses a more descriptive phrase for small amounts.
  • Improves indentation and overall code structure.

To ensure this change doesn't affect other parts of the codebase, let's check for other usages of utils.formatAmount:

#!/bin/bash
# Search for other usages of utils.formatAmount
rg "utils\.formatAmount" --type typescript

Line range hint 1-93: General improvements for code cleanliness and error handling

While the main changes look good, here are some suggestions for overall improvement:

  1. Remove commented-out code: The code for fetching token price (around line 60) is commented out. If it's no longer needed, consider removing it entirely to keep the code clean.

  2. Improve error handling: In the generateMetadata function, consider setting a default title in case of an error. This ensures that a title is always set, even if the link details fetch fails.

  3. Consider refactoring createURL: If this function is used in other parts of the application, it might be beneficial to move it to a utility file for better code organization and reusability.

Here's a suggestion for improved error handling in generateMetadata:

try {
    // ... existing code ...
} catch (e) {
    console.error('Error fetching link details:', e);
    title = 'Claim your tokens!'; // Set a default title in case of error
}

To check if createURL is used elsewhere and might benefit from being moved to a utility file:

✅ Verification successful

General improvements for code cleanliness and error handling

While the main changes look good, here are some suggestions for overall improvement:

  1. Remove commented-out code: The code for fetching token price (around line 60) is commented out. If it's no longer needed, consider removing it entirely to keep the code clean.

  2. Improve error handling: In the generateMetadata function, consider setting a default title in case of an error. This ensures that a title is always set, even if the link details fetch fails.

  3. Evaluate the necessity of refactoring createURL: Currently, createURL is only used within page.tsx. If you anticipate using it elsewhere in the future, consider moving it to a utility file for better code organization and reusability. Otherwise, keeping it within the current file maintains simplicity.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other usages of createURL function
rg "createURL\(" --type typescript

Length of output: 79


Script:

#!/bin/bash
# Search for other usages of createURL function in TypeScript files
rg "createURL\(" -g "*.ts" -g "*.tsx"

Length of output: 242

src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (1)

Line range hint 86-94: Verify the link text and href for consistency with user flow

Based on previous feedback, similar components in the send flow use the link text 'Make a payment yourself!' and href '/send'. Please ensure that 'Request a payment yourself!' and href '/request/create' are appropriate for the request flow in this context.

🧰 Tools
🪛 Biome

[error] 11-11: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Comment on lines 4 to 21
export async function get(bankAccount: string): Promise<boolean> {
bankAccount = bankAccount.replace(/\s/g, '')
const response = await fetch(`/api/peanut/iban/validate-bank-account`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
bankAccount,
}),
})

if (response.status !== 200) {
return false
} else {
return true
}
} No newline at end of file
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

Improve function naming, error handling, and return value

The current implementation of the get function has several areas for improvement:

  1. Function naming:

    • The name get is too generic. Consider renaming it to validateBankAccount or isBankAccountValid to better describe its purpose.
  2. Input validation:

    • Add a check for empty or null input before processing.
  3. Error handling:

    • Implement proper error handling for network errors and parsing errors.
    • Consider returning more detailed error information.
  4. Return value:

    • Instead of a boolean, return an object with more details about the validation result.
  5. Code style:

    • Remove the unnecessary else after the return statement.

Here's a suggested refactoring of the function:

export async function validateBankAccount(bankAccount: string): Promise<{ isValid: boolean; error?: string }> {
    if (!bankAccount) {
        return { isValid: false, error: 'Bank account is required' };
    }

    const cleanedBankAccount = bankAccount.replace(/\s/g, '');

    try {
        const response = await fetch(`/api/peanut/iban/validate-bank-account`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ bankAccount: cleanedBankAccount }),
        });

        if (!response.ok) {
            const errorData = await response.json().catch(() => ({}));
            return { 
                isValid: false, 
                error: errorData.message || `Validation failed with status: ${response.status}`
            };
        }

        const data = await response.json();
        return { isValid: true, ...data };
    } catch (error) {
        return { 
            isValid: false, 
            error: error instanceof Error ? error.message : 'An unknown error occurred'
        };
    }
}

This refactored version addresses the issues mentioned above and provides more robust error handling and informative return values.

Comment on lines 5 to 7
export async function POST(request: NextRequest) {
try {
const { link } = await request.json()
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 15, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add input validation for the 'link' parameter.

While the current implementation is concise, it might fail silently if the 'link' is not provided in the request body. Consider adding explicit input validation to handle cases where 'link' is missing or invalid.

Here's a suggested improvement:

 export async function POST(request: NextRequest) {
     try {
         const { link } = await request.json()
+        if (!link || typeof link !== 'string') {
+            return new NextResponse('Invalid or missing link parameter', { status: 400 })
+        }
📝 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
export async function POST(request: NextRequest) {
try {
const { link } = await request.json()
export async function POST(request: NextRequest) {
try {
const { link } = await request.json()
if (!link || typeof link !== 'string') {
return new NextResponse('Invalid or missing link parameter', { status: 400 })
}

Copy link
Contributor

Choose a reason for hiding this comment

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

valid

Copy link
Contributor

Choose a reason for hiding this comment

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

@jjramirezn, glad to hear that you find the suggestion valid! Let me know if you have any questions or need further assistance.

🐰😊

Comment on lines 9 to 23
const response = await fetch(`${consts.PEANUT_API_URL}/get-link-info`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
link,
apiKey: process.env.PEANUT_API_KEY,
}),
})

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}

const data = await response.json()
return NextResponse.json(data)
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

Enhance security and add documentation for the API call.

The API call is well-structured, but there are two areas for improvement:

  1. For better security, consider moving the API key to the request headers instead of the body.
  2. Add a comment explaining the purpose of this API call for better code documentation.

Here's a suggested improvement:

+        // Fetch link information from Peanut API
         const response = await fetch(`${consts.PEANUT_API_URL}/get-link-info`, {
             method: 'POST',
-            headers: { 'Content-Type': 'application/json' },
+            headers: { 
+                'Content-Type': 'application/json',
+                'X-API-Key': process.env.PEANUT_API_KEY
+            },
             body: JSON.stringify({
                 link,
-                apiKey: process.env.PEANUT_API_KEY,
             }),
         })
📝 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 fetch(`${consts.PEANUT_API_URL}/get-link-info`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
link,
apiKey: process.env.PEANUT_API_KEY,
}),
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const data = await response.json()
return NextResponse.json(data)
// Fetch link information from Peanut API
const response = await fetch(`${consts.PEANUT_API_URL}/get-link-info`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.PEANUT_API_KEY
},
body: JSON.stringify({
link,
}),
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const data = await response.json()
return NextResponse.json(data)

Comment on lines 24 to 28
} catch (error) {
console.error('Error fetching user stats:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
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

Improve error handling and logging.

The current error handling can be enhanced in the following ways:

  1. Use a more specific error message in the console.log.
  2. Consider returning more informative error responses to the client, while being careful not to expose sensitive information.
  3. Differentiate between different types of errors (e.g., network errors, API errors, validation errors).

Here's a suggested improvement:

     } catch (error) {
-        console.error('Error fetching user stats:', error)
-        return new NextResponse('Internal Server Error', { status: 500 })
+        console.error('Error fetching link info:', error)
+        if (error instanceof Error) {
+            return new NextResponse(error.message, { status: 500 })
+        } else {
+            return new NextResponse('An unexpected error occurred', { status: 500 })
+        }
     }
 }
📝 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
} catch (error) {
console.error('Error fetching user stats:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
} catch (error) {
console.error('Error fetching link info:', error)
if (error instanceof Error) {
return new NextResponse(error.message, { status: 500 })
} else {
return new NextResponse('An unexpected error occurred', { status: 500 })
}
}
}

Comment on lines 22 to 23
<div className="flex w-full flex-col items-center justify-center gap-2">
<div className="flex w-full flex-col items-center justify-center gap-2">
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 15, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove duplicate nested <div> elements

There are two identical <div> elements nested inside each other. This duplication is unnecessary and may lead to unintended styling or layout issues.

Apply this diff to remove the duplicate <div>:

                 {dataAvailable && (
-                    <div className="flex w-full flex-col items-center justify-center gap-2">
                     <div className="flex w-full flex-col items-center justify-center gap-2">

Committable suggestion was skipped due to low confidence.

Copy link
Contributor

Choose a reason for hiding this comment

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

look into this

Copy link
Contributor

Choose a reason for hiding this comment

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

@jjramirezn, I have looked into this and confirmed that there are two identical <div> elements nested inside each other in the AlreadyPaidLinkView component when dataAvailable is true. This duplication is unnecessary and may lead to unintended styling or layout issues.

We can simplify the code by removing one of the duplicate <div> elements:

{dataAvailable && (
    <div className="flex w-full flex-col items-center justify-center gap-2">
        {/* Rest of the content */}
    </div>
)}

This adjustment will maintain the intended layout without the extra nesting.


🧠 Learnings used
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-03T17:43:19.914Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.

Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-08T20:13:42.967Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.

Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-08T20:13:44.480Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.

Comment on lines +32 to +76
<div className="flex w-full flex-row items-center justify-between gap-1 px-2 text-h8 text-gray-1">
<div className="flex w-max flex-row items-center justify-center gap-1">
<label className="font-bold">Token</label>
</div>
<span className="flex flex-row items-center justify-center gap-1 text-center text-sm font-normal leading-4">
{claimLinkData?.tokenSymbol}
</span>
</div>
)}
{tokenAmountAvailable && (
<div className="flex w-full flex-row items-center justify-between gap-1 px-2 text-h8 text-gray-1">
<div className="flex w-max flex-row items-center justify-center gap-1">
<label className="font-bold">Amount</label>
</div>
<span className="flex flex-row items-center justify-center gap-1 text-center text-sm font-normal leading-4">
{claimLinkData?.tokenAmount}
</span>
</div>
)}
{chainAvailable && (
<div className="flex w-full flex-row items-center justify-between gap-1 px-2 text-h8 text-gray-1">
<div className="flex w-max flex-row items-center justify-center gap-1">
<label className="font-bold">Chain</label>
</div>
<span className="flex flex-row items-center justify-center gap-1 text-center text-sm font-normal leading-4">
<img
src={consts.supportedPeanutChains.find((detail) => detail.chainId === claimLinkData?.chainId)?.icon
.url
}
className="h-6 w-6"
/>
{chainName}
</span>
</div>
)}
{senderAddressAvailable && (
<div className="flex w-full flex-row items-center justify-between gap-1 px-2 text-h8 text-gray-1">
<div className="flex w-max flex-row items-center justify-center gap-1">
<label className="font-bold">Sender</label>
</div>
<span className="flex flex-row items-center justify-center gap-1 text-center text-sm font-normal leading-4">
{utils.shortenAddress(claimLinkData?.senderAddress)}
</span>
</div>
)}
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

Refactor repeated rendering blocks into a reusable component

The blocks of code from lines 32 to 76 that render token information are repetitive. Consider creating a reusable component or a helper function to handle these sections. This will enhance maintainability and reduce code duplication.

Comment on lines +17 to +20
const tokenSymbolAvailable: boolean = claimLinkData?.tokenSymbol != undefined
const tokenAmountAvailable: boolean = claimLinkData?.tokenAmount != undefined
const chainAvailable: boolean = claimLinkData?.chainId != undefined
const senderAddressAvailable: boolean = claimLinkData?.senderAddress != undefined
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

Simplify null checking with a helper function

The checks for tokenSymbolAvailable, tokenAmountAvailable, chainAvailable, and senderAddressAvailable can be simplified by creating a helper function to reduce redundancy.

Consider defining a helper function:

const isAvailable = (value: any): boolean => value != null;

And then use it:

-const tokenSymbolAvailable: boolean = claimLinkData?.tokenSymbol != undefined
-const tokenAmountAvailable: boolean = claimLinkData?.tokenAmount != undefined
-const chainAvailable: boolean = claimLinkData?.chainId != undefined
-const senderAddressAvailable: boolean = claimLinkData?.senderAddress != undefined
+const tokenSymbolAvailable = isAvailable(claimLinkData?.tokenSymbol)
+const tokenAmountAvailable = isAvailable(claimLinkData?.tokenAmount)
+const chainAvailable = isAvailable(claimLinkData?.chainId)
+const senderAddressAvailable = isAvailable(claimLinkData?.senderAddress)

Comment on lines +58 to +60
src={consts.supportedPeanutChains.find((detail) => detail.chainId === claimLinkData?.chainId)?.icon
.url
}
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

Simplify the image source assignment for clarity

The assignment of the src property for the image can be made more readable by simplifying the expression.

Apply this diff to improve readability:

-src={consts.supportedPeanutChains.find((detail) => detail.chainId === claimLinkData?.chainId)?.icon
-            .url
-}
+src={
+  consts.supportedPeanutChains.find(
+    (detail) => detail.chainId === claimLinkData?.chainId
+  )?.icon.url
+}
📝 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
src={consts.supportedPeanutChains.find((detail) => detail.chainId === claimLinkData?.chainId)?.icon
.url
}
src={
consts.supportedPeanutChains.find(
(detail) => detail.chainId === claimLinkData?.chainId
)?.icon.url
}

export const AlreadyClaimedLinkView = ({ claimLinkData }: { claimLinkData: interfaces.ILinkDetails | undefined }) => {
const router = useRouter()

const chainName = consts.supportedPeanutChains && consts.supportedPeanutChains.find((chain) => chain.chainId == claimLinkData?.chainId)?.name
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

Simplify optional chaining in chainName assignment

You can simplify the assignment of chainName by leveraging optional chaining without the need for the logical AND && operator.

Apply this diff to simplify the code:

-const chainName = consts.supportedPeanutChains && consts.supportedPeanutChains.find((chain) => chain.chainId == claimLinkData?.chainId)?.name
+const chainName = consts.supportedPeanutChains?.find((chain) => chain.chainId === claimLinkData?.chainId)?.name
📝 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 chainName = consts.supportedPeanutChains && consts.supportedPeanutChains.find((chain) => chain.chainId == claimLinkData?.chainId)?.name
const chainName = consts.supportedPeanutChains?.find((chain) => chain.chainId === claimLinkData?.chainId)?.name
🧰 Tools
🪛 Biome

[error] 15-15: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

@Hugo0 Hugo0 requested a review from jjramirezn October 16, 2024 08:52
@Hugo0
Copy link
Contributor

Hugo0 commented Oct 16, 2024

2 small nits:

    1. PR would benefit from motivation for PR in the description (short 1-2sentences)
    1. I'd say this is more of a chore than a fix, but honestly it doesn't rlly matter

@panosfilianos panosfilianos changed the title fix: Add additional data to already claimed links and already paid requests chore: Add additional data to already claimed links and already paid requests Oct 16, 2024
<label className="text-h2">Sorry, this link has already been paid.</label>
<label className="text-h8 font-bold ">
This link previously requested{' '}
{requestLinkData?.tokenSymbol ??
Copy link
Contributor

Choose a reason for hiding this comment

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

thought: there is loss of functionality here

Before we were trying to get a token symbol if there is none from the data. Now we just trust the data we get. I actually like the new way better but it warrants fixing why sometimes we don't have data from the request link itself. In the short term this change WILL result in some data previously shown to not be shown anymore

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True. I would expect this operation to take place where data is populated (i.e. where requestLinkData is formed, populate as lines 16-19 do). I, actually, do not have a clear idea on why requestLinkData won't have all required fields populated already. Thus, I opted to show the data that is directly available through requestLinkData.

// This file holds all relevant link utils
// TODO: bring all link utils from general.utils.ts to here

export async function get(bankAccount: string): Promise<boolean> {
Copy link
Contributor

Choose a reason for hiding this comment

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

comment(blocking): where is this used?

also, we should probably use better naming

Copy link
Contributor

@jjramirezn jjramirezn left a comment

Choose a reason for hiding this comment

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

  • The function in link.utils.ts seems to be unused
  • Fix deployment (using pnpm build you can check whats failing, but there is a duplicated div tag maybe is that)

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

🧹 Outside diff range and nitpick comments (2)
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (2)

10-16: LGTM! Consider simplifying the chainName constant.

The introduction of new constants to check the availability of properties from requestLinkData improves code readability and maintainability. The dataAvailable boolean is a good approach for conditional rendering.

Consider simplifying the chainName constant using optional chaining:

- const chainName = consts.supportedPeanutChains && consts.supportedPeanutChains.find((chain) => chain.chainId == requestLinkData?.chainId)?.name
+ const chainName = consts.supportedPeanutChains?.find((chain) => chain.chainId == requestLinkData?.chainId)?.name

This change makes the code more concise while maintaining the same functionality.

🧰 Tools
🪛 Biome

[error] 11-11: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


46-61: LGTM! Enhanced chain information display. Consider simplifying icon URL retrieval.

The new block for displaying chain information is well-structured and consistent with previous blocks. The addition of the chain icon enhances visual recognition, improving the user experience.

Consider simplifying the chain icon URL retrieval:

- src={consts.supportedPeanutChains.find((detail) => detail.chainId === requestLinkData?.chainId)?.icon
-                                .url
- }
+ src={consts.supportedPeanutChains.find((detail) => detail.chainId === requestLinkData?.chainId)?.icon?.url}

This change reduces nesting and improves readability while maintaining the same functionality.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between f6b52c3 and 9287d84.

📒 Files selected for processing (1)
  • src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (1 hunks)
🧰 Additional context used
📓 Learnings (1)
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (3)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-08T20:13:42.967Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-03T17:43:19.914Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-08T20:13:44.480Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.
🪛 Biome
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx

[error] 11-11: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (5)
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (5)

21-25: LGTM! Improved conditional rendering and user information.

The introduction of conditional rendering based on dataAvailable ensures that additional information is only shown when relevant data is present. The label "This link previously contained:" provides clear context for the information that follows, improving user understanding.


26-35: LGTM! Clear presentation of token symbol.

The new block for displaying the token symbol is well-structured and consistent with the component's styling. The conditional rendering ensures that this information is only shown when available, preventing potential display issues with incomplete data.


36-45: LGTM! Consistent presentation of token amount.

The new block for displaying the token amount maintains consistency with the token symbol block in terms of structure and styling. This addition provides valuable information about the transaction amount, enhancing the user's understanding of the previously paid link.


62-71: LGTM! Well-implemented requester address display.

The new block for displaying the requester's address maintains consistency with previous blocks in terms of structure and styling. The use of utils.shortenAddress() is a good practice, improving readability and maintaining a level of privacy for the requester.


Line range hint 1-73: Great job on enhancing the AlreadyPaidLinkView component!

The changes made to this component significantly improve the presentation of information for already paid links. The introduction of conditional rendering for each piece of data (token symbol, amount, chain, and requester address) ensures that users only see relevant information when it's available. This approach enhances the user experience by providing more detailed and structured information about the previously paid link.

The consistent use of styling and layout throughout the component maintains a cohesive look and feel. The addition of the chain icon is a nice touch that improves visual recognition.

Overall, these changes make the component more informative and user-friendly. Great work on improving this part of the UI!

🧰 Tools
🪛 Biome

[error] 11-11: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

@panosfilianos
Copy link
Contributor Author

New updates:

  • Removing unused functions (previously added to fetch additional link data, which halfway we decided was not needed)
  • pnpm run dev executes properly
  • Removed uneeded div
    Thanks a lot for the comments @jjramirezn

@jjramirezn
Copy link
Contributor

pnpm dev compiles lazily and I don't know if checks types, the error that shows with pnpm build is the following:

2024-10-16_08-24

Also I think is better not to commit the empty links.utils.ts file (when we start moving some functions there we can create it)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (2)
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (2)

46-61: LGTM: Chain information display block with a minor suggestion.

The addition of this block to display the chain information when available is well-implemented. It maintains consistency with the previous blocks and includes a nice touch with the chain icon.

Consider adding a fallback for the chain icon in case the find operation doesn't return a result:

 <img
-    src={consts.supportedPeanutChains.find((detail) => detail.chainId === requestLinkData?.chainId)?.icon
-                        .url
+    src={consts.supportedPeanutChains.find((detail) => detail.chainId === requestLinkData?.chainId)?.icon
+                        ?.url ?? '/path/to/fallback/icon.png'
     }
     className="h-6 w-6"
 />

This ensures that even if the chain icon is not found, a default icon is displayed, preventing potential rendering issues.


Line range hint 1-73: Address potential loss of functionality in token symbol display.

As mentioned in a previous comment by jjramirezn, there might be a loss of functionality regarding the token symbol fallback. Previously, there was an attempt to get a token symbol if none was present in the data. Now, we're directly trusting the data we receive.

To address this:

  1. Investigate why requestLinkData sometimes doesn't have all required fields populated.
  2. Consider implementing the token symbol fallback logic where requestLinkData is formed, ensuring all necessary data is available before reaching this component.
  3. If the above is not feasible in the short term, you might want to reimplement the fallback logic in this component temporarily:
const tokenSymbol = requestLinkData?.tokenSymbol || getTokenSymbolFallback(requestLinkData);

This ensures that we maintain the previous functionality while improving the overall display of information.

Would you like assistance in implementing this fallback logic or in investigating why requestLinkData might be incomplete?

🧰 Tools
🪛 Biome

[error] 11-11: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 645410e and caec2a7.

📒 Files selected for processing (1)
  • src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (1 hunks)
🧰 Additional context used
📓 Learnings (1)
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (3)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-08T20:13:42.967Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-03T17:43:19.914Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#412
File: src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx:37-37
Timestamp: 2024-10-08T20:13:44.480Z
Learning: The files 'src/components/Claim/Generic/AlreadyClaimed.view.tsx' and 'NotFound.view.tsx' are part of the send flow, so the link text 'Make a payment yourself!' and href '/send' should remain as they are.
🪛 Biome
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx

[error] 11-11: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (5)
src/components/Request/Pay/Views/GeneralViews/AlreadyPaid.view.tsx (5)

12-16: LGTM: Introduction of availability constants improves code clarity.

The introduction of these constants to check the availability of specific properties in requestLinkData improves code readability and maintainability. The dataAvailable boolean effectively summarizes the availability of any relevant data.


21-25: LGTM: Conditional rendering of additional information.

The addition of this conditional rendering block is a good improvement. It ensures that the additional information about the previously paid link is only displayed when relevant data is available, enhancing the user experience.


26-35: LGTM: Token symbol display block.

The addition of this block to display the token symbol when available is well-implemented. It follows the component's design patterns and uses conditional rendering appropriately.


36-45: LGTM: Token amount display block.

The addition of this block to display the token amount when available is well-implemented. It maintains consistency with the previous block and the overall component design, using conditional rendering appropriately.


62-71: LGTM: Requester's address display block.

The addition of this block to display the requester's address when available is well-implemented. It maintains consistency with the previous blocks and appropriately uses the utils.shortenAddress function to display the address in a user-friendly format.


export const AlreadyPaidLinkView = ({ requestLinkData }: { requestLinkData: _consts.IRequestLinkData | undefined }) => {

const chainName = consts.supportedPeanutChains && consts.supportedPeanutChains.find((chain) => chain.chainId == requestLinkData?.chainId)?.name
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

Simplify the chainName constant using optional chaining.

The chainName constant can be simplified using optional chaining for better readability and conciseness.

Apply this diff to refactor the code:

- const chainName = consts.supportedPeanutChains && consts.supportedPeanutChains.find((chain) => chain.chainId == requestLinkData?.chainId)?.name
+ const chainName = consts.supportedPeanutChains?.find((chain) => chain.chainId == requestLinkData?.chainId)?.name
📝 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 chainName = consts.supportedPeanutChains && consts.supportedPeanutChains.find((chain) => chain.chainId == requestLinkData?.chainId)?.name
const chainName = consts.supportedPeanutChains?.find((chain) => chain.chainId == requestLinkData?.chainId)?.name
🧰 Tools
🪛 Biome

[error] 11-11: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

@panosfilianos
Copy link
Contributor Author

  • Fixed minor build bug
  • Removed utils file (to add a Task from TODO: moving utils functions around links on their own file)
  • Vercel deploys successfully

Copy link
Contributor

@jjramirezn jjramirezn left a comment

Choose a reason for hiding this comment

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

Approved, merging.

Nice PR, Looks much better now!

2024-10-16_11-35

@jjramirezn jjramirezn merged commit 9e3f07a into develop Oct 16, 2024
@jjramirezn jjramirezn deleted the fix/link-receipts branch October 16, 2024 14:38
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