Skip to content

Commit

Permalink
feat: added support for cobadged cards
Browse files Browse the repository at this point in the history
  • Loading branch information
Sanskar2001 committed Aug 14, 2024
1 parent 3c82cfb commit a974990
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 15 deletions.
37 changes: 37 additions & 0 deletions src/CardSchemeComponent.res
Original file line number Diff line number Diff line change
@@ -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>
}
10 changes: 10 additions & 0 deletions src/CardUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type cardProps = (
string,
(string => string) => unit,
int,
string,
)

type expiryProps = (
Expand Down Expand Up @@ -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
})
}
2 changes: 2 additions & 0 deletions src/Components/DynamicFields.res
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ let make = (
"",
_ => (),
0,
"",
)

let defaultExpiryProps = (
Expand Down Expand Up @@ -163,6 +164,7 @@ let make = (
cardError,
_,
maxCardLength,
cardScheme,
) = switch cardProps {
| Some(cardProps) => cardProps
| None => defaultCardProps
Expand Down
3 changes: 2 additions & 1 deletion src/Components/PaymentInputField.res
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ let make = (
~placeholder="",
~appearance: CardThemeType.appearance,
~className="",
~rightIconClassName="-ml-10",
~inputRef,
) => {
let {themeObj, config} = Recoil.useRecoilValueFromAtom(configAtom)
Expand Down Expand Up @@ -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 {
Expand Down
27 changes: 17 additions & 10 deletions src/Payment.res
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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 {
[]
}
Expand Down Expand Up @@ -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,
Expand All @@ -395,6 +401,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => {
cardError,
setCardError,
maxCardLength,
cardBrand,
)

let expiryProps: CardUtils.expiryProps = (
Expand Down
7 changes: 3 additions & 4 deletions src/Payments/CardPayment.res
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,9 @@ let make = (
cardError,
setCardError,
maxCardLength,
cardBrand,
) = cardProps

let cardBrand = React.useMemo(() => {
cardNumber->CardUtils.getCardBrand
}, [cardNumber])

let (
isExpiryValid,
setIsExpiryValid,
Expand Down Expand Up @@ -207,6 +204,7 @@ let make = (
nickname,
isCardBrandValid,
isManualRetryEnabled,
cardProps,
))
useSubmitPaymentData(submitCallback)

Expand Down Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions src/RenderPaymentMethods.res
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ let make = (
_,
_,
maxCardLength,
_,
) = cardProps

let (
Expand Down
1 change: 1 addition & 0 deletions src/SingleLineCardPayment.res
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ let make = (
_,
_,
maxCardLength,
_,
) = cardProps

let (
Expand Down

0 comments on commit a974990

Please sign in to comment.