Skip to content

feat(product-options): enhance product option selectors with price formatting and sorting #47

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

Merged
merged 5 commits into from
Mar 14, 2025

Conversation

jaruesink
Copy link
Contributor

@jaruesink jaruesink commented Mar 14, 2025

  • Updated ProductOptionSelectorRadio and ProductOptionSelectorSelect components to include price information (minPrice, maxPrice, exactPrice, discountPercentage).
  • Implemented sorting of option values by price in both selectors.
  • Added currencyCode prop to support dynamic currency formatting.
  • Refactored option value filtering to ensure unique values are displayed.
  • Enhanced price display logic to show ranges and discounts where applicable.

Summary by CodeRabbit

  • New Features

    • Enhanced product option selectors now display comprehensive pricing details, including ranges and discounts, with support for multiple currencies.
    • Product options are sorted by price for a clearer, more intuitive shopping experience.
    • The product page now features improved option selection behavior and breadcrumb navigation for easier browsing and enhanced usability.
    • New utility functions for better handling of product variants and pricing information have been introduced.
  • Bug Fixes

    • Improved logic for filtering and selecting product options to ensure relevant selections are displayed correctly.

…rmatting and sorting

- Updated ProductOptionSelectorRadio and ProductOptionSelectorSelect components to include price information (minPrice, maxPrice, exactPrice, discountPercentage).
- Implemented sorting of option values by price in both selectors.
- Added currencyCode prop to support dynamic currency formatting.
- Refactored option value filtering to ensure unique values are displayed.
- Enhanced price display logic to show ranges and discounts where applicable.
@jaruesink jaruesink requested review from Copilot and dwene March 14, 2025 20:15
Copy link

coderabbitai bot commented Mar 14, 2025

Walkthrough

The pull request updates the product option selector components and product page template to include enhanced pricing information and discount handling. Both the radio and select option components have been modified to support additional optional pricing fields and a new currency code property, which leads to changes in filtering, sorting, and formatting the option display. The product template now features improved variant selection logic and breadcrumb generation, while the product utility functions have been enhanced with detailed documentation, explicit return types, and a new method for variant selection based on user options.

Changes

File(s) Change Summary
apps/storefront/app/components/product/ProductOptionSelectorRadio.tsx
apps/storefront/app/components/product/ProductOptionSelectorSelect.tsx
Updated the ProductOptionSelectorProps interface to include optional pricing fields (minPrice, maxPrice, exactPrice, discountPercentage), and added a new currencyCode prop. Modified filtering, sorting, and rendering logic to format price and discount information for each product option.
apps/storefront/app/templates/ProductTemplate.tsx Introduced a new function getBreadcrumbs and added detailed JSDoc comments to getAddToCartValidator and variantIsSoldOut. Removed the ProductReviews component, updated default values using a useMemo hook, refined variant and options selection logic, and added a useEffect hook to initialize state. Applied minor formatting changes for layout adjustments.
apps/storefront/libs/util/products.ts Added JSDoc comments to several utility functions, refined filtering logic and variable naming in the matrix population, updated return types in selectVariantFromMatrixBySelectedOptions and selectDiscountFromVariant to explicitly return undefined when appropriate, and introduced the new function getVariantFromSelectedOptions to retrieve specific variants based on selected options.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant OptionSelector
  participant ProductTemplate
  participant ProductUtility

  User->>OptionSelector: Select an option (radio/select)
  OptionSelector->>ProductTemplate: Emit onChange event with new value
  ProductTemplate->>ProductUtility: getVariantFromSelectedOptions(selectedOptions)
  ProductUtility-->>ProductTemplate: Return matching variant (or undefined)
  ProductTemplate->>OptionSelector: Update component state with variant & pricing details
  OptionSelector-->>User: Render updated option display (price, discount)
Loading

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.

📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5fa67b5 and 53925f8.

📒 Files selected for processing (1)
  • apps/storefront/app/templates/ProductTemplate.tsx (10 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/storefront/app/templates/ProductTemplate.tsx

🪧 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 generate docstrings to generate docstrings for 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

medusajs bot commented Mar 14, 2025

Name Deployment Status Preview Link Timestamp
Medusa Starter 🔴 Failed Preview Fri, 14 Mar 2025 20:39:45 GMT

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances product option selectors by adding price formatting, sorting by price, discount display, and dynamic currency support while refactoring option filtering for uniqueness. Key changes include:

  • Updating both selector components to include price range/discount information.
  • Adding a new currencyCode prop and using a price formatting utility.
  • Refactoring helper functions in the products library to support these new price features.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
apps/storefront/app/components/product/ProductOptionSelectorSelect.tsx Updates to sort options by price and display formatted pricing details.
apps/storefront/app/templates/ProductTemplate.tsx Adjustments to default option values and option change handling with currency support.
apps/storefront/libs/util/products.ts Enhancements in generating option combinations and pricing details.
apps/storefront/app/components/product/ProductOptionSelectorRadio.tsx Similar price formatting and sorting logic added to the radio selector.
Comments suppressed due to low confidence (1)

apps/storefront/app/components/product/ProductOptionSelectorRadio.tsx:78

  • [nitpick] Using the index as a key may lead to rendering issues if the list is re-ordered or modified. Consider using a unique property from optionValue (e.g., optionValue.value) as the key.
key={valueIndex}

Copy link

@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

🧹 Nitpick comments (6)
apps/storefront/app/components/product/ProductOptionSelectorSelect.tsx (3)

10-16: Ensure consistent typing for optional fields
Consider verifying that the data source always supplies numeric values or handle fallback for undefined to avoid runtime errors.


33-35: Duplicate filtering check
Filtering out duplicate values is good. Be sure the original data doesn't rely on repeated items for any logic.


37-43: Sorting by price
Sorting logic looks correct. Consider clarifying tie-breaking rules for identical prices if needed.

apps/storefront/app/templates/ProductTemplate.tsx (2)

38-38: New imports for pricing
The additional utilities getCheapestProductVariant and getVariantFinalPrice suggest future-ready price manipulation. Ensure any exceptional cases (e.g., no variants) are handled.


173-175: Variant selection memo
Performance optimization with useMemo is good. Verify correct variant resolution when partial or unknown options are selected.

apps/storefront/app/components/product/ProductOptionSelectorRadio.tsx (1)

54-117: Price & discount rendering
The logic for displaying a single price, range, or discount annotation is well done. The UI feedback for disabled state and checked items is also clear.

Consider extracting price formatting into a shared helper if reused across multiple components to further streamline the radio rendering.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1ed594d and 195b4a9.

📒 Files selected for processing (4)
  • apps/storefront/app/components/product/ProductOptionSelectorRadio.tsx (1 hunks)
  • apps/storefront/app/components/product/ProductOptionSelectorSelect.tsx (1 hunks)
  • apps/storefront/app/templates/ProductTemplate.tsx (10 hunks)
  • apps/storefront/libs/util/products.ts (2 hunks)
🔇 Additional comments (25)
apps/storefront/app/components/product/ProductOptionSelectorSelect.tsx (5)

2-2: Nice usage of formatPrice utility
No additional instructions needed, everything looks good.


20-20: Currency code integration
Adding the currencyCode prop is consistent with the dynamic price formatting goal.


23-28: Component signature extension
Great job adding currencyCode to the component signature to support price formatting.


45-71: Comprehensive price formatting
The logic constructing labels with price ranges and discounts is thorough and user-friendly.


77-77: Placeholder option
Providing a default "Select one" option is helpful for guiding users.

apps/storefront/app/templates/ProductTemplate.tsx (6)

48-52: Clear JSDoc comment
The descriptive JSDoc on getAddToCartValidator is helpful for future maintainers.


74-78: Breadcrumb doc block
Excellent addition of a JSDoc comment for breadcrumb generation. Improves codebase clarity.


112-116: Sold-out detection doc
Clear explanation of the inventory-based sold-out logic.


130-161: Enhanced default values logic
The use of useMemo for constructing default option values from the first variant is efficient. Make sure the fallback logic covers edge cases when no variants or option values exist.

Please confirm through tests or QA that products with zero variants do not break this logic.


180-221: Refined product option generation
Sorting and filtering logic for options based on the user’s prior selections appears well-structured. Good approach to ensuring the correct values remain available while preserving discount labeling.


394-394: Passing currency code to selector
Properly passing currencyCode ensures consistent display of all relevant prices.

apps/storefront/app/components/product/ProductOptionSelectorRadio.tsx (6)

5-5: Import formatPrice
Nice addition for consistent price formatting in radio option labels.


11-18: Extended option values type
Adding additional price and discount fields to the option values is logical for displaying more info.


22-22: Currency code prop
Introducing currencyCode fosters dynamic currency formatting for each radio option.


25-30: Component signature update
The updated signature neatly integrates currencyCode.


35-38: Duplicate value filtering
Ensuring uniqueness prevents confusion from redundant entries.


40-45: Price-based sorting
Sorting options by ascending price is intuitive.

apps/storefront/libs/util/products.ts (8)

8-15: Great addition of JSDoc comments and explicit return types!

The JSDoc documentation and explicit return type for getVariantBySelectedOptions improve code clarity and maintainability. This makes the function's purpose and behavior more evident to other developers.


17-27: Good refactoring of the variant matrix function

The renamed parameter from priceMatrix to matrix is more appropriate, and the added explicit return of undefined improves code clarity. The JSDoc comment clearly explains the function's purpose.


38-49: Improved documentation and null handling in discount calculation

The enhanced JSDoc comment and explicit return type for selectDiscountFromVariant are good improvements. The code comment on line 47 also clarifies the early return condition.


59-75: Good addition of documentation for combinatorial logic

The JSDoc comment for the option combinations generator function helps other developers understand the purpose of this potentially complex code. The typing for the reduce accumulator in line 69 is also a good improvement.


77-102: Great improvements to the variant matrix builder

The JSDoc comment and variable name change from priceMatrix to matrix better reflect the function's purpose. The code comments also provide more clarity on what the function is doing.


104-159: Significant improvement to option filtering logic

The enhanced documentation and refactored logic in getFilteredOptionValues provide a clearer approach to filtering option values. The special handling for the first option and the consideration of option sequence is a good improvement that ensures users only see valid combinations.


161-245: Well-implemented price range and discount calculation

The pricing logic has been significantly improved with proper handling of:

  • Different behaviors for final vs. non-final options
  • Price range calculation when multiple prices exist
  • Exact price and discount percentage for final options

This enhances the user experience by providing more comprehensive pricing information.


247-271: Well-structured new variant selection function

The new getVariantFromSelectedOptions function is a valuable addition:

  • Properly handles empty selections
  • Uses clear early returns
  • Includes thorough documentation
  • Implements efficient filtering logic to find matching variants

This will be useful for determining the exact variant that matches a user's selections.

jaruesink and others added 4 commits March 14, 2025 15:18
…lect.tsx


Using the logical OR operator here may wrongly fallback when aPrice is 0. Consider using the nullish coalescing operator (??) as in: 'const aPrice = a.minPrice ?? a.exactPrice ?? 0;' to correctly handle 0 values.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…rolledOptions helper function

- Introduced updateControlledOptions function to streamline the logic for updating controlled options based on user selection.
- Refactored handleOptionChangeBySelect and handleOptionChangeByRadio to utilize the new helper function for improved code clarity and maintainability.
@jaruesink jaruesink merged commit 0263754 into main Mar 14, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant