Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE-205] Refactor AddressInput and GeneralRecipientInput #465

Merged
merged 6 commits into from
Oct 23, 2024

Conversation

jjramirezn
Copy link
Contributor

In two components with similar logic (validating an input) there was an issue that if the input changed while still validating, it would enter in a loop alternating between both values, this PR fixes that by:

  • Abstracting the input and validation logic into a separate common component
  • Better management of the state of the component, if we trigger the useffect again, then we discard the result of the previous validation, that way we only get the most recent

Copy link

vercel bot commented Oct 21, 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 22, 2024 0:21am

Copy link
Contributor

coderabbitai bot commented Oct 21, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

This pull request includes significant updates across several components related to recipient data handling and validation in a React application. The InitialClaimLinkView, AddressInput, GeneralRecipientInput, and InitialView components have been modified to streamline props and state management, enhancing the control flow and error handling. A new ValidatedInput component has been introduced to encapsulate input validation logic, replacing complex structures in existing components. These changes collectively aim to improve the clarity and maintainability of the codebase.

Changes

File Path Change Summary
src/components/Claim/Link/Initial.view.tsx Updated InitialClaimLinkView to use GeneralRecipientUpdate type in props and modified _estimatePoints function logic, integrating it into a useEffect hook. Enhanced error handling in handleClaimLink and handleIbanRecipient functions.
src/components/Global/AddressInput/index.tsx Simplified AddressInput props by replacing multiple properties with an onUpdate prop. Removed internal state variables and replaced them with a ValidatedInput component for address validation.
src/components/Global/GeneralRecipientInput/index.tsx Modified GeneralRecipientInput to accept a recipient object and an onUpdate callback. Streamlined state management using useRef and refactored address validation logic.
src/components/Global/ValidatedInput/index.tsx Introduced a new ValidatedInput component that encapsulates input validation logic, including debouncing and error handling. Defined InputUpdate type for structured updates.
src/components/Request/Create/Views/Initial.view.tsx Updated InitialView to use InputUpdate type for the AddressInput component's onUpdate prop, simplifying state management for recipient address input.

Possibly related PRs

  • Estimating points and saving them #381: This PR focuses on estimating points and saving them, which is directly related to the changes in the InitialClaimLinkView component where the logic for estimating points was refined and integrated into the component's state management.
  • Fix/cashout rework #388: This PR involves a cashout rework, which includes modifications to the InitialClaimLinkView component, enhancing its handling of recipient data and error states, aligning with the changes made in the main PR.
  • fix(request): correctly identify native tokens #434: This PR addresses issues with correctly identifying native tokens, which relates to the handling of recipient addresses and validation in the InitialClaimLinkView, enhancing the overall functionality of the component.
  • fix(request): allow user to connect on request pay page #449: This PR improves the user experience on the request pay page, ensuring users can connect their wallets, which is relevant to the changes in the InitialClaimLinkView that involve managing user interactions and states.
  • Feat/move liquidation address earlier #458: This PR refactors the InitialClaimLinkView to improve error handling and user feedback, which aligns with the changes made in the main PR regarding error management and recipient validation.
  • [ISSUE-213] refactor: load token pair onto selector context before advancing from pay #461: This PR refactors the token pair loading process in the selector context, which is relevant to the changes in the InitialClaimLinkView that involve managing token and chain information effectively.

Suggested labels

Being worked on

Suggested reviewers

  • panosfilianos

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

🧹 Outside diff range and nitpick comments (7)
src/components/Request/Create/Views/Initial.view.tsx (2)

134-141: LGTM: Improved AddressInput props and handling.

The changes to the AddressInput component improve its usage by consolidating multiple props into a single onUpdate function. This simplifies the component's interface and makes it easier to manage state updates.

A minor suggestion:

Consider destructuring the update object in the onUpdate function for improved readability:

-onUpdate={(update: InputUpdate) => {
-    setRecipientAddress(update.value)
-    setInputChanging(update.isChanging)
-    setIsValidRecipient(update.isValid)
+onUpdate={({ value, isChanging, isValid }: InputUpdate) => {
+    setRecipientAddress(value)
+    setInputChanging(isChanging)
+    setIsValidRecipient(isValid)
}}

Line range hint 153-153: LGTM: Improved submit button disabled state.

The updated disabled state for the submit button enhances user experience by preventing submissions with invalid or incomplete data. This change aligns well with the new input validation approach.

Consider adding visual feedback or tooltips to indicate why the button is disabled. This could improve user understanding and guide them to complete the form correctly. For example:

<button
    className="wc-disable-mf btn-purple btn-xl"
    onClick={handleOnNext}
    disabled={!isValidRecipient || inputChanging || isLoading || !_tokenValue}
    title={
        !isValidRecipient ? "Invalid recipient address" :
        inputChanging ? "Input is changing" :
        !_tokenValue ? "Token value is required" :
        isLoading ? "Processing..." : ""
    }
>
    {isLoading ? (
        <div className="flex w-full flex-row items-center justify-center gap-2">
            <Loading /> {loadingState}
        </div>
    ) : (
        'Confirm'
    )}
</button>

This addition would provide more context to the user about why the button is disabled.

src/components/Global/AddressInput/index.tsx (1)

6-11: Consider making placeholder prop optional in AddressInputProps

Since a default value is provided for placeholder in the component, consider making it optional in the AddressInputProps type definition to reflect that it's not required when using the component.

Apply this diff to adjust the type definition:

 type AddressInputProps = {
-    placeholder: string
+    placeholder?: string
     value: string
     onUpdate: (update: InputUpdate) => void
     className?: string
 }
src/components/Global/ValidatedInput/index.tsx (4)

32-33: Simplify the condition for better readability

The condition '' === debouncedValue || debouncedValue === previousValueRef.current can be simplified to improve readability.

Apply this diff to simplify the condition:

-if ('' === debouncedValue || debouncedValue === previousValueRef.current) {
+if (!debouncedValue || debouncedValue === previousValueRef.current) {
     return
 }

17-25: Type the component using FC from React

For consistency and better type enforcement, consider typing the ValidatedInput component with React.FC.

Apply this diff:

 const ValidatedInput = ({
+const ValidatedInput: React.FC<ValidatedInputProps> = ({
     label,
     placeholder = '',
     value,
     debounceTime = 300,
     onUpdate,
     validate,
     className,
 }: ValidatedInputProps) => {

80-82: Reconsider setting spellCheck to "false"

The spellCheck attribute is set to "false". If the input field is expected to accept text that might benefit from spell checking, consider enabling it.


85-91: Add accessible labels to the loading spinner

The loading spinner lacks accessible labels, which may hinder users relying on screen readers.

Apply this diff to include aria-label:

 <div
     className="h-4 w-4 animate-spin rounded-full border-2 border-solid border-current border-r-transparent motion-reduce:animate-none"
     role="status"
+    aria-label="Validating input"
 />
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between cb65b74 and b0e2e20.

📒 Files selected for processing (5)
  • src/components/Claim/Link/Initial.view.tsx (4 hunks)
  • src/components/Global/AddressInput/index.tsx (1 hunks)
  • src/components/Global/GeneralRecipientInput/index.tsx (1 hunks)
  • src/components/Global/ValidatedInput/index.tsx (1 hunks)
  • src/components/Request/Create/Views/Initial.view.tsx (2 hunks)
🧰 Additional context used
🔇 Additional comments (2)
src/components/Request/Create/Views/Initial.view.tsx (2)

Line range hint 1-172: Overall assessment: Improvements align with PR objectives.

The changes in this file successfully refactor the AddressInput component usage and improve state management for input validation. The modifications enhance the user experience by providing better control over form submission based on input validity and changes.

Key improvements:

  1. Introduction of the InputUpdate type for consolidated input handling.
  2. Simplified AddressInput component interface.
  3. Enhanced submit button disabled state logic.

These changes align well with the PR objectives of refactoring input components and resolving issues related to input validation loops. The code is now more maintainable and provides a clearer flow of data and validation states.


10-10: LGTM: New import for input validation.

The addition of the InputUpdate import from ValidatedInput is appropriate for the changes in this component. It suggests an improvement in input handling and validation.

To ensure this import is used correctly throughout the file, run the following script:

✅ Verification successful

Verification Successful: InputUpdate is correctly used in the file.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of InputUpdate in the file

# Test: Check if InputUpdate is used in the file
rg -q 'InputUpdate' src/components/Request/Create/Views/Initial.view.tsx && echo "InputUpdate is used in the file" || echo "InputUpdate is not used in the file"

# Test: Check how InputUpdate is used in the file
rg 'InputUpdate' src/components/Request/Create/Views/Initial.view.tsx

Length of output: 337

src/components/Global/AddressInput/index.tsx Show resolved Hide resolved
src/components/Global/ValidatedInput/index.tsx Outdated Show resolved Hide resolved
src/components/Global/ValidatedInput/index.tsx Outdated Show resolved Hide resolved
src/components/Global/GeneralRecipientInput/index.tsx Outdated Show resolved Hide resolved
src/components/Global/GeneralRecipientInput/index.tsx Outdated Show resolved Hide resolved
src/components/Claim/Link/Initial.view.tsx Outdated Show resolved Hide resolved
src/components/Claim/Link/Initial.view.tsx Outdated Show resolved Hide resolved
src/components/Claim/Link/Initial.view.tsx Outdated Show resolved Hide resolved
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 (3)
src/components/Global/GeneralRecipientInput/index.tsx (3)

29-62: Well-refactored checkAddress function.

The checkAddress function has been significantly improved:

  • Wrapping it in useCallback is good for performance.
  • The refactored logic is more concise and easier to follow.
  • Returning a boolean aligns with the single responsibility principle.

One minor suggestion:

Consider extracting the regex for US account numbers into a named constant at the top of the file for better readability and maintainability:

const US_ACCOUNT_REGEX = /^[0-9]{6,17}$/;

Then use it in the function:

} else if (US_ACCOUNT_REGEX.test(recipient)) {

64-89: Well-structured onInputUpdate function.

The onInputUpdate function is well-implemented:

  • Using useCallback is good for performance.
  • It effectively handles both valid and invalid input cases.
  • The update object construction aligns well with the GeneralRecipientUpdate type.

A minor suggestion for improved clarity:

Consider using object shorthand notation when the property name matches the variable name. For example:

_update = {
    recipient:
        'ens' === recipientType.current
            ? { address: resolvedAddress.current, name: update.value }
            : { address: update.value, name: undefined },
    type: recipientType.current,
    isValid: true,
    isChanging: update.isChanging,
    errorMessage,  // Using shorthand here
}

This makes the code slightly more concise and easier to read.


91-101: Simplified render logic with ValidatedInput.

The use of the ValidatedInput component greatly simplifies the render logic and improves the overall structure of the component. The props passed to ValidatedInput align well with its expected functionality.

A minor suggestion for consistency:

Consider using object shorthand notation for the className prop to match the style used in other parts of the component:

<ValidatedInput
    placeholder={placeholder}
    label="To"
    value={recipient.name ?? recipient.address}
    debounceTime={750}
    validate={checkAddress}
    onUpdate={onInputUpdate}
    className  // Using shorthand here
/>

This small change would make the prop passing style consistent throughout the component.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b0e2e20 and b07575d.

📒 Files selected for processing (3)
  • src/components/Claim/Link/Initial.view.tsx (3 hunks)
  • src/components/Global/GeneralRecipientInput/index.tsx (1 hunks)
  • src/components/Global/ValidatedInput/index.tsx (1 hunks)
🧰 Additional context used
🔇 Additional comments (12)
src/components/Global/GeneralRecipientInput/index.tsx (3)

2-21: Improved imports and type definitions.

The changes to imports and type definitions reflect a positive shift towards more functional programming practices and improved type safety. The new GeneralRecipientUpdate type provides a clear structure for updates, which enhances code readability and maintainability.


24-27: Improved component structure and state management.

The new component signature is more concise and clearly defines the expected props. The use of useRef for recipientType, errorMessage, and resolvedAddress is an excellent optimization, as these values don't need to trigger re-renders when changed.


Line range hint 1-105: Overall excellent refactoring of the GeneralRecipientInput component.

This refactoring represents a significant improvement in code structure, performance, and maintainability:

  1. Shift towards functional programming with useCallback and useRef.
  2. Improved type definitions for better type safety.
  3. Simplified component structure with clear prop definitions.
  4. Well-refactored checkAddress and onInputUpdate functions.
  5. Use of ValidatedInput component for cleaner render logic.

These changes align well with React best practices and modern JavaScript/TypeScript conventions. The code is now more readable, efficient, and easier to maintain.

src/components/Global/ValidatedInput/index.tsx (6)

3-16: Well-defined prop types and interfaces

The component's props and update types are clearly defined, enhancing type safety and readability.


31-57: Effective use of useEffect for handling validation

The implementation correctly handles asynchronous validation with proper cleanup to prevent memory leaks. The isStale flag effectively prevents state updates on unmounted components.


59-66: Appropriate debouncing logic in useEffect

The use of setTimeout within useEffect effectively debounces the input value, preventing excessive validation calls and improving performance.


67-70: Correct handling of input changes

The handleChange function appropriately updates the state and notifies parent components of changes.


73-75: Avoid duplicate class names in conditional rendering

The conditional class names might lead to duplicate border classes, potentially causing styling issues.


77-79: Enhance accessibility by associating the label with the input

The input field lacks an explicit association with the label, which can affect screen reader users.

src/components/Claim/Link/Initial.view.tsx (3)

1-2: Import statement correctly updated.

The import of GeneralRecipientUpdate is accurate, resolving the previous typo issue.


246-263: Properly handle async operations inside useEffect.

As previously noted, calling estimatePoints directly inside useEffect can lead to unhandled promises and potential issues. Consider defining and invoking an async function within useEffect for better error handling and cleanup.


468-477: onUpdate handler correctly updates state.

The onUpdate function successfully updates the state based on GeneralRecipientUpdate, ensuring proper management of recipient data.

Copy link
Contributor

@nezz0746 nezz0746 left a comment

Choose a reason for hiding this comment

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

LGTM, nice abstraction for inputs

Note: Didn't even knew we had a notion bot here...

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