@W-18771949 Get rule based bonus products from API#2641
@W-18771949 Get rule based bonus products from API#2641sf-madhuri-uppu wants to merge 11 commits intofeature/rule-based-bonus-productsfrom
Conversation
🎉 Snyk checks have passed. No issues have been found so far.✅ security/snyk check is complete. No issues have been found. (View Details) ✅ license/snyk check is complete. No issues have been found. (View Details) |
packages/template-retail-react-app/app/hooks/use-bonus-product-search.js
Show resolved
Hide resolved
packages/template-retail-react-app/app/components/product-view/index.jsx
Show resolved
Hide resolved
packages/template-retail-react-app/app/components/product-view/index.jsx
Outdated
Show resolved
Hide resolved
packages/template-retail-react-app/app/components/product-view/index.jsx
Outdated
Show resolved
Hide resolved
|
@sf-vrushal-kulkarni I made changes to product view component so we will not able to see rule based promotions on cart page. I can see list based promotions on the bonus modal on PDP. Let me look into why we are seeing rule based promotion after adding the item to cart for the second time. Screen.Recording.2025-06-26.at.10.11.57.PM.mov |
|
https://github.com/user-attachments/assets/8cea3bda-c01c-4ece-9023-0d2d2dd63ae9 |
| const [promotionIdToSearch, setPromotionIdToSearch] = useState(null) | ||
| const {data: bonusProductSearchResult} = useBonusProductSearch(promotionIdToSearch) | ||
|
|
||
| // State to track all promotion IDs and their results |
There was a problem hiding this comment.
The business logic here seems to be isolated to bonus products only. Is it possibel to extract it out into a hook to reduce code in this component? E.g useBonusProduct()
| maxBonusItems: | ||
| bonusItemsForModal?.promotionIdToMaxBonusItemsMap?.[promotionIdToSearch] | ||
| } | ||
| ruleBasedPromotionsRef.current.push(currentPromotionResult) |
There was a problem hiding this comment.
For React ref, we are re-assigning current
ruleBasedPromotionsRef.current = currentPromotionResult
| productId: bonusProduct.productId, | ||
| productName: bonusProduct.productName, | ||
| c_productUrl: bonusProduct.c_productUrl | ||
| } |
There was a problem hiding this comment.
If this is the data structure we are dealing for bonus product. You can avoid doing this here by taking advantage of react-query select data transformation during useBonusProductSearch hook. then the data returns will always have this shape.
https://tanstack.com/query/v4/docs/framework/react/reference/useQuery
See useProductViewModal for an example
P/s: You can definitely create promotion id map from here as well if that is more convenient and reduce the amount of data transformation logic in the handleAddToCart
| if (pendingPromotionIds.length > 0) { | ||
| const nextPromotionId = pendingPromotionIds[0] | ||
| setPendingPromotionIds((prev) => prev.slice(1)) | ||
| setPromotionIdToSearch(nextPromotionId) |
There was a problem hiding this comment.
Can we filter out any pending promotion from useBonusProducts hook select transformation step so all promotions returned are always valid promotion.
//pseu-do code
const {data: bonusProd} = useBonusProductSearch(args, {
enabdle: !! promotionId,
select: (res) => {
const validPromo = res.hits.map(promo => !promo.isPending)
return res.hits.map (promo => ({
id: ...,
name: ...
})
}
} )
| let listBasedBonusProducts = newBonusItems.filter( | ||
| (item) => item.bonusProducts | ||
| ) | ||
| // Collect all promotion IDs for rule-based promotions |
There was a problem hiding this comment.
Let's clean up comment here unless it is necessary. Too much comments accumulated over time can affect bundle size if every line of code has one comment explaining what it does
| isOpen: false, | ||
| data: {}, | ||
| bonusProducts: basket?.bonusDiscountLineItems || [] | ||
| existingBonusProducts: basket?.bonusDiscountLineItems || [] |
There was a problem hiding this comment.
why changing it to existingBonusProducts? What made it different from bonusProd. from this hook POV, it only cares about basket.bonusDiscountLineItems as bonusProd. What is the non-existingBonusProd if we take this name?
So any un-added/un-set items from outside that is not added to cart is irrelavent
| .filter(Boolean) | ||
|
|
||
| //create maps of promotionId to id and maxBonusItems for rule based promotions | ||
| const {promotionIdToIdMap, promotionIdToMaxBonusItemsMap} = |
There was a problem hiding this comment.
Can we reduce this logic here if we take advantage of useProductSearch hook select for data transformation?

Description
Fetch rule based bonus products by calling product search API. Handle scenarios where a product can qualify for multiple rule based and list based promotions (sometimes both too). Formatted the response of rule based promotions to look like list based response so that modal's logic need not differentiate between the 2 kinds.
Screen.Recording.2025-06-27.at.12.57.55.AM.mov
Types of Changes
Changes
How to Test-Drive This PR
Checklists
General
Accessibility Compliance
You must check off all items in one of the follow two lists:
or...
Localization