diff --git a/src/CardSchemeComponent.res b/src/CardSchemeComponent.res new file mode 100644 index 000000000..b52179e67 --- /dev/null +++ b/src/CardSchemeComponent.res @@ -0,0 +1,37 @@ +module CoBadgeCardSchemeDropDown = { + @react.component + let make = (~cardNumber, ~setCardBrand) => { + <select + className="w-[15px]" + onChange={ev => { + let target = ev->ReactEvent.Form.target + let value = target["value"] + setCardBrand(_ => value) + }}> + <option disabled=true> {"Select a card brand"->React.string} </option> + {cardNumber + ->CardUtils.getCoBadgesCardSchemes + ->Array.mapWithIndex((item: string, i) => { + <option key={Int.toString(i)} value=item className="opacity-0 w-0 h-0"> + {item->React.string} + </option> + }) + ->React.array} + </select> + } +} + +@react.component +let make = (~cardNumber, ~paymentType, ~cardBrand, ~setCardBrand, ~isCardCoBadged=false) => { + let cardType = React.useMemo1(_ => cardBrand->CardUtils.getCardType, [cardBrand]) + let animate = cardType == NOTFOUND ? "animate-slideLeft" : "animate-slideRight" + + let cardBrandIcon = React.useMemo1( + _ => CardUtils.getCardBrandIcon(cardType, paymentType), + [cardBrand], + ) + <div className={`${animate} flex items-center`}> + cardBrandIcon + {isCardCoBadged ? <CoBadgeCardSchemeDropDown cardNumber setCardBrand /> : React.null} + </div> +} diff --git a/src/CardUtils.res b/src/CardUtils.res index 9ad523fb7..421f476ef 100644 --- a/src/CardUtils.res +++ b/src/CardUtils.res @@ -26,6 +26,7 @@ type cardProps = ( string, (string => string) => unit, int, + string, ) type expiryProps = ( @@ -651,3 +652,12 @@ let getPaymentMethodBrand = (customerMethod: PaymentType.customerMethods) => { ) } } + +let getCoBadgesCardSchemes = cardNumber => { + CardPattern.cardPatterns->Array.reduce([], (acc, item) => { + if String.match(cardNumber, item.pattern)->Option.isSome { + acc->Array.push(item.issuer) + } + acc + }) +} diff --git a/src/Components/DynamicFields.res b/src/Components/DynamicFields.res index 3fc1d3b90..f12709881 100644 --- a/src/Components/DynamicFields.res +++ b/src/Components/DynamicFields.res @@ -109,6 +109,7 @@ let make = ( "", _ => (), 0, + "", ) let defaultExpiryProps = ( @@ -163,6 +164,7 @@ let make = ( cardError, _, maxCardLength, + cardScheme, ) = switch cardProps { | Some(cardProps) => cardProps | None => defaultCardProps diff --git a/src/Components/PaymentInputField.res b/src/Components/PaymentInputField.res index 98ba1809d..27913c92c 100644 --- a/src/Components/PaymentInputField.res +++ b/src/Components/PaymentInputField.res @@ -20,6 +20,7 @@ let make = ( ~placeholder="", ~appearance: CardThemeType.appearance, ~className="", + ~rightIconClassName="-ml-10", ~inputRef, ) => { let {themeObj, config} = Recoil.useRecoilValueFromAtom(configAtom) @@ -131,7 +132,7 @@ let make = ( </div> </RenderIf> </div> - <div className={`relative flex -ml-10 items-center`}> {rightIcon} </div> + <div className={`relative flex ${rightIconClassName} items-center`}> {rightIcon} </div> </div> <RenderIf condition={innerLayout === Spaced}> {switch errorString { diff --git a/src/Payment.res b/src/Payment.res index 5f51a1429..f0cb937a7 100644 --- a/src/Payment.res +++ b/src/Payment.res @@ -47,13 +47,15 @@ let make = (~paymentMode, ~integrateError, ~logger) => { let (isZipValid, setIsZipValid) = React.useState(_ => None) let (isCardSupported, setIsCardSupported) = React.useState(_ => None) - let (cardBrand, maxCardLength) = React.useMemo(() => { - let brand = getCardBrand(cardNumber) - let maxLength = getMaxLength(cardNumber) - let isNotBancontact = selectedOption !== "bancontact_card" && brand == "" - !showFields && isNotBancontact ? (cardScheme, maxLength) : (brand, maxLength) + let maxCardLength = React.useMemo(() => { + getMaxLength(cardNumber) }, (cardNumber, cardScheme, showFields)) + let cardBrand = getCardBrand(cardNumber) + let isNotBancontact = selectedOption !== "bancontact_card" && cardBrand == "" + let (cardBrand, setCardBrand) = React.useState(_ => + !showFields && isNotBancontact ? cardScheme : cardBrand + ) let supportedCardBrands = React.useMemo(() => { let cardPaymentMethod = paymentMethodListValue.payment_methods->Array.find(ele => ele.payment_method === "card") @@ -246,7 +248,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => { } let cardNetwork = { if cardBrand != "" { - [("card_network", cardNumber->CardUtils.getCardBrand->JSON.Encode.string)] + [("card_network", cardBrand->JSON.Encode.string)] } else { [] } @@ -377,11 +379,15 @@ let make = (~paymentMode, ~integrateError, ~logger) => { None }, (isExpiryValid, isExpiryComplete(cardExpiry))) + React.useEffect(() => { + // Console.log("changing card brand" ++ cardBrand ++ cardNumber) + setCardBrand(_ => cardNumber->CardUtils.getCardBrand) + None + }, [cardNumber]) + let icon = React.useMemo(() => { - let animate = cardType == NOTFOUND ? "animate-slideLeft" : "animate-slideRight" - let cardBrandIcon = getCardBrandIcon(cardType, paymentType) - <div className=animate> cardBrandIcon </div> - }, (cardType, paymentType)) + <CardSchemeComponent cardNumber paymentType cardBrand setCardBrand isCardCoBadged=true /> + }, (cardType, paymentType, cardBrand, cardNumber)) let cardProps: CardUtils.cardProps = ( isCardValid, @@ -395,6 +401,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => { cardError, setCardError, maxCardLength, + cardBrand, ) let expiryProps: CardUtils.expiryProps = ( diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res index 7e1e811fd..eee784376 100644 --- a/src/Payments/CardPayment.res +++ b/src/Payments/CardPayment.res @@ -35,12 +35,9 @@ let make = ( cardError, setCardError, maxCardLength, + cardBrand, ) = cardProps - let cardBrand = React.useMemo(() => { - cardNumber->CardUtils.getCardBrand - }, [cardNumber]) - let ( isExpiryValid, setIsExpiryValid, @@ -207,6 +204,7 @@ let make = ( nickname, isCardBrandValid, isManualRetryEnabled, + cardProps, )) useSubmitPaymentData(submitCallback) @@ -258,6 +256,7 @@ let make = ( ? "border-b-0" : ""} name=TestUtils.cardNoInputTestId + rightIconClassName="-ml-12" /> <div className="flex flex-row w-full place-content-between" diff --git a/src/RenderPaymentMethods.res b/src/RenderPaymentMethods.res index d02c2bbfe..0cb63bbaa 100644 --- a/src/RenderPaymentMethods.res +++ b/src/RenderPaymentMethods.res @@ -24,6 +24,7 @@ let make = ( _, _, maxCardLength, + _, ) = cardProps let ( diff --git a/src/SingleLineCardPayment.res b/src/SingleLineCardPayment.res index f2821dc02..45bb34121 100644 --- a/src/SingleLineCardPayment.res +++ b/src/SingleLineCardPayment.res @@ -26,6 +26,7 @@ let make = ( _, _, maxCardLength, + _, ) = cardProps let (