-
Notifications
You must be signed in to change notification settings - Fork 108
feat: unified view for saved and more payment methods screen #1194
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
base: main
Are you sure you want to change the base?
Conversation
|
Hmm. Quite confusing experience. If “Saved” implies all (saved) payment methods, why should it have a card icon. Right next it to is “Cards” with a card icon again. Worth revisiting |
Thanks for pointing this out, we’ll revisit the icons. |
656a1b5
🚫 Missing Linked IssueHi 👋 This pull request does not appear to be linked to any open issue yet. Linking your PR to an issue helps keep the project tidy and ensures the issue is closed automatically. ✔️ How to fix this
Once linked, this check will pass automatically on your next push or when you re-run the workflow. Thanks for helping maintainers! 🙌 |
🚫 Missing Linked IssueHi 👋 This pull request does not appear to be linked to any open issue yet. Linking your PR to an issue helps keep the project tidy and ensures the issue is closed automatically. ✔️ How to fix this
Once linked, this check will pass automatically on your next push or when you re-run the workflow. Thanks for helping maintainers! 🙌 |
94d440a
src/Components/SavedMethods.res
Outdated
| let renderSavedCards = (cardsArr: array<PaymentType.customerMethods>) => { | ||
| cardsArr | ||
| ->Array.mapWithIndex((obj, i) => | ||
| <SavedCardItem | ||
| key={i->Int.toString} | ||
| setPaymentToken | ||
| isActive={paymentTokenVal == obj.paymentToken} | ||
| paymentItem=obj | ||
| brandIcon={obj->getPaymentMethodBrand} | ||
| index=i | ||
| savedCardlength | ||
| cvcProps | ||
| setRequiredFieldsBody | ||
| /> | ||
| ) | ||
| ->React.array | ||
| } | ||
|
|
||
| let clickToPayElement = { | ||
| <RenderIf condition={clickToPayConfig.isReady == Some(true)}> | ||
| <ClickToPayAuthenticate | ||
| loggerState | ||
| savedMethods | ||
| isClickToPayAuthenticateError | ||
| setIsClickToPayAuthenticateError | ||
| setPaymentToken | ||
| paymentTokenVal | ||
| cvcProps | ||
| getVisaCards | ||
| setIsClickToPayRememberMe | ||
| closeComponentIfSavedMethodsAreEmpty | ||
| /> | ||
| </RenderIf> | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a react component
src/Components/SavedMethods.res
Outdated
| {if enableSavedPaymentShimmer { | ||
| <PaymentElementShimmer.SavedPaymentCardShimmer /> | ||
| } else { | ||
| <RenderIf condition={!showPaymentMethodsScreen}> {bottomElement} </RenderIf> | ||
| <RenderIf condition={!showPaymentMethodsScreen}> | ||
| {displayMergedSavedMethods ? mergedViewBottomElement : bottomElement} | ||
| </RenderIf> | ||
| }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try this
<RenderIf condition={enableSavedPaymentShimmer}>
<PaymentElementShimmer.SavedPaymentCardShimmer />
</RenderIf>
<RenderIf condition={!enableSavedPaymentShimmer && !showPaymentMethodsScreen}>
{displayMergedSavedMethods ? mergedViewBottomElement : bottomElement}
</RenderIf>
src/Components/SavedMethods.res
Outdated
| let mergedViewBottomElement = { | ||
| <div | ||
| className="PickerItemContainer" tabIndex={0} role="region" ariaLabel="Saved payment methods"> | ||
| {renderSavedCards(cardOptionDetails)} | ||
| <div | ||
| className={`transition-all duration-300 ease-in-out overflow-hidden | ||
| ${showMore ? "max-h-0 opacity-0" : "max-h-screen opacity-100"} | ||
| `}> | ||
| {renderSavedCards(dropDownOptionsDetails)} | ||
| </div> | ||
| clickToPayElement | ||
| </div> | ||
| } | ||
|
|
||
| let bottomElement = { | ||
| <div | ||
| className="PickerItemContainer" tabIndex={0} role="region" ariaLabel="Saved payment methods"> | ||
| {savedMethods | ||
| ->Array.mapWithIndex((obj, i) => | ||
| <SavedCardItem | ||
| key={i->Int.toString} | ||
| setPaymentToken | ||
| isActive={paymentTokenVal == obj.paymentToken} | ||
| paymentItem=obj | ||
| brandIcon={obj->getPaymentMethodBrand} | ||
| index=i | ||
| savedCardlength | ||
| cvcProps | ||
| setRequiredFieldsBody | ||
| /> | ||
| ) | ||
| ->React.array} | ||
| <RenderIf condition={clickToPayConfig.isReady == Some(true)}> | ||
| <ClickToPayAuthenticate | ||
| loggerState | ||
| savedMethods | ||
| isClickToPayAuthenticateError | ||
| setIsClickToPayAuthenticateError | ||
| setPaymentToken | ||
| paymentTokenVal | ||
| cvcProps | ||
| getVisaCards | ||
| setIsClickToPayRememberMe | ||
| closeComponentIfSavedMethodsAreEmpty | ||
| /> | ||
| </RenderIf> | ||
| <RenderIf condition={!displayMergedSavedMethods}> {renderSavedCards(savedMethods)} </RenderIf> | ||
| clickToPayElement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why these are not functional components?
src/PaymentElement.res
Outdated
| if displayMergedSavedMethods && selectedOption == "saved_methods" { | ||
| setShowPaymentMethodsScreen(_ => false) | ||
| } else if displayMergedSavedMethods { | ||
| setShowPaymentMethodsScreen(_ => true) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if displayMergedSavedMethods && selectedOption == "saved_methods" { | |
| setShowPaymentMethodsScreen(_ => false) | |
| } else if displayMergedSavedMethods { | |
| setShowPaymentMethodsScreen(_ => true) | |
| } | |
| let showScreen = | |
| displayMergedSavedMethods && selectedOption !== "saved_methods"; | |
| setShowPaymentMethodsScreen(showScreen); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would not be equivalent to the previous case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this
if displayMergedSavedMethods {
setShowPaymentMethodsScreen(_ => selectedOption != "saved_methods")
}
Sanskar2001
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please check the comments
src/Components/ShowMoreButton.res
Outdated
| style={ | ||
| fontSize: "14px", | ||
| float: "left", | ||
| fontWeight: "500", | ||
| width: "fit-content", | ||
| color: themeObj.colorPrimary, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why inlining styling is required here?
| let enableSavedPaymentShimmer = React.useMemo(() => { | ||
| savedCardlength === 0 && | ||
| !showPaymentMethodsScreen && | ||
| (loadSavedCards === PaymentType.LoadingSavedCards || clickToPayConfig.isReady->Option.isNone) | ||
| }, (savedCardlength, loadSavedCards, showPaymentMethodsScreen, clickToPayConfig.isReady)) | ||
| (loadSavedCards === PaymentType.LoadingSavedCards || clickToPayConfig.isReady->Option.isNone) && | ||
| !displayMergedSavedMethods | ||
| }, ( | ||
| savedCardlength, | ||
| loadSavedCards, | ||
| showPaymentMethodsScreen, | ||
| clickToPayConfig.isReady, | ||
| displayMergedSavedMethods, | ||
| )) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to simplify this condition for better readability.
src/PaymentElement.res
Outdated
| | _ => | ||
| <RenderIf | ||
| condition={!displaySavedPaymentMethods && | ||
| condition={(!displaySavedPaymentMethods || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we simplify this? It's too many conditions inside a prop - not readable
src/PaymentElement.res
Outdated
| <RenderIf | ||
| condition={((displaySavedPaymentMethods && savedMethods->Array.length > 0) || | ||
| isShowPaymentMethodsDependingOnClickToPay) && showPaymentMethodsScreen}> | ||
| isShowPaymentMethodsDependingOnClickToPay) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we simplify this? It's too many conditions inside a prop - not readable
src/Components/ShowMoreButton.res
Outdated
| onClick={_ => { | ||
| setShowMore(_ => !showMore) | ||
| }}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| onClick={_ => { | |
| setShowMore(_ => !showMore) | |
| }}> | |
| onClick={_ => setShowMore(prev => !prev) }> |
Type of Change
Description
Added a parameter inside
layoutobject, named assavedMethodsLayout, it is an object having structure asbased upon which if there are saved payment methods and
displayMergedSavedMethodsis passed as true then instead of coming on a separate saved payment methods screen, it will come in either tabs flow or accordion flow depending upon the layout.maxSavedItemsis used to configure how many saved methods we want to show initially and then the rest can be shown after clicking on show more.Screen.Recording.2025-08-26.at.4.47.04.PM.mov
How did you test it?
Tested the following cases for both Accordion view and Tabs View :-
When saved payment methods are present
displaySavedPaymentMethodsisfalse,displayMergedSavedMethodsisfalseortrueNo saved payment methods tabdisplaySavedPaymentMethodsistrue,displayMergedSavedMethodsisfalseNormal flow Saved payment methods screendisplaySavedPaymentMethodsistrue,displayMergedSavedMethodsistrueSaved payment methods in tabs or accordionWhen No saved payment methods are present
each case will have no saved payment methods
Checklist
npm run re:build