Skip to content
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

feat: phone country dropdown added #270

Merged
merged 57 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
7abe06a
feat: phone country dropdown added
Apr 3, 2024
4ba3fc7
style: style changes
Apr 3, 2024
e4f3b39
fix: get value of country code via recoil
Apr 3, 2024
35479ed
Merge branch 'main' into phone-number-validations
vsrivatsa-edinburgh Apr 4, 2024
1ff80b0
Merge branch 'main' into phone-number-validations
Apr 4, 2024
e1ad9aa
Merge branch 'main' into phone-number-validations
Apr 5, 2024
1ca3bc4
fix: phone country code comments addressed
Apr 5, 2024
dc2d030
fix: revert payment element
Apr 5, 2024
05ad185
fix: country code append
Apr 5, 2024
30a8add
Merge branch 'main' into phone-number-validations
Apr 9, 2024
412d1e4
feat: country options added
Apr 10, 2024
6b021ff
fix: map key
Apr 10, 2024
e18af17
Merge branch 'main' into phone-number-validations
Apr 10, 2024
49ba733
fix: belt functions removed
Apr 12, 2024
1c8dfa0
Merge branch 'main' of github.com:juspay/hyperswitch-web into phone-n…
Apr 14, 2024
39a0168
fix: dropdown changes added
Apr 15, 2024
3b1b776
Merge branch 'main' of github.com:juspay/hyperswitch-web into phone-n…
Apr 17, 2024
b3fc22d
Merge branch 'main' of github.com:juspay/hyperswitch-web into phone-n…
Apr 17, 2024
e000ee9
Merge branch 'main' into phone-number-validations
Apr 17, 2024
62ce705
Merge branch 'main' into phone-number-validations
Apr 18, 2024
c638e66
Merge branch 'main' into phone-number-validations
Apr 18, 2024
df49579
fix: comments addressed
Apr 18, 2024
d14006e
fix: comments addressed
Apr 18, 2024
162d704
fix: label comment addressed
Apr 18, 2024
f2c710c
Merge branch 'main' into phone-number-validations
Apr 18, 2024
f306c6a
fix: remove duplicate countries
Apr 19, 2024
10c3f3f
Merge branch 'phone-number-validations' of github.com:juspay/hyperswi…
Apr 19, 2024
5a77010
Merge branch 'main' into phone-number-validations
Apr 22, 2024
af61102
fix: comments addressed
Apr 23, 2024
762e20f
Merge branch 'phone-number-validations' of github.com:juspay/hyperswi…
Apr 23, 2024
1f754b6
fix: added breakpoints to debug
Apr 24, 2024
4c3df29
chore(release): 0.45.2 [skip ci]
semantic-release-bot Apr 24, 2024
32563dd
Merge branch 'main' into phone-number-validations
Apr 25, 2024
ca96770
fix: apple pay debugging (#333)
vsrivatsa-edinburgh Apr 25, 2024
f99edde
chore(release): 0.45.3 [skip ci]
semantic-release-bot Apr 25, 2024
34d4828
fix: apple pay debug
prafulkoppalkar Apr 25, 2024
43ccd89
chore(release): 0.45.4 [skip ci]
semantic-release-bot Apr 25, 2024
bc992df
fix: country code multiple same code fix
Apr 26, 2024
d47b822
Merge branch 'main' into phone-number-validations
Apr 26, 2024
6a737e2
fix: backgroundColor fix added
Apr 26, 2024
2af60e9
fix: spacing and only numeric char added
Apr 26, 2024
c6d5757
Merge branch 'main' of github.com:juspay/hyperswitch-web into phone-n…
Apr 29, 2024
dac50dc
fix: changelog updated
Apr 29, 2024
338d762
fix: revert elements changes
Apr 29, 2024
3ab4292
Merge branch 'main' into phone-number-validations
Apr 29, 2024
f3c1eba
Merge branch 'main' of github.com:juspay/hyperswitch-web into phone-n…
May 6, 2024
5c4a474
Merge branch 'main' into phone-number-validations
prafulkoppalkar May 6, 2024
c683854
fix: apple pay revert
May 6, 2024
7aea58c
fix: comments addressed
May 6, 2024
ec58ae6
Merge branch 'main' into phone-number-validations
prafulkoppalkar May 6, 2024
550294d
Merge branch 'main' into phone-number-validations
May 7, 2024
d5c6b4c
Merge branch 'main' into phone-number-validations
prafulkoppalkar May 8, 2024
38945c4
Merge branch 'main' into phone-number-validations
May 9, 2024
a49fa04
Merge branch 'main' into phone-number-validations
May 10, 2024
7b4195f
Merge branch 'main' of github.com:juspay/hyperswitch-web into phone-n…
May 10, 2024
288c04f
Merge branch 'phone-number-validations' of github.com:juspay/hyperswi…
May 10, 2024
d6f8ae7
Merge branch 'main' into phone-number-validations
prafulkoppalkar May 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 78 additions & 25 deletions src/Components/DropdownField.res
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
type optionType = {
value: string,
label?: string,
displayValue?: string,
}

let updateArrayOfStringToOptionsTypeArray = arrayOfString =>
arrayOfString->Array.map(item => {
value: item,
})

let defaultValue = {
value: "",
}

open RecoilAtoms
@react.component
let make = (
~appearance: CardThemeType.appearance,
~value,
~setValue,
~isDisplayValueVisible=false,
~displayValue=?,
~setDisplayValue=?,
~fieldName,
~options,
~options: array<optionType>,
~disabled=false,
~className="",
~width="w-full",
) => {
let {themeObj, localeString, config} = Recoil.useRecoilValueFromAtom(configAtom)
let {readOnly} = Recoil.useRecoilValueFromAtom(optionAtom)
Expand All @@ -25,13 +44,31 @@ let make = (
let target = ev->ReactEvent.Form.target
let value = target["value"]
setValue(value)
if isDisplayValueVisible {
let findDisplayValue =
options
->Array.find(ele => ele.value === value)
->Option.getOr(defaultValue)

switch setDisplayValue {
| Some(setDisplayValue) =>
setDisplayValue(_ => findDisplayValue.displayValue->Option.getOr(value))
| None => ()
}
}
}
let disbaledBG = React.useMemo(() => {
themeObj.colorBackground
}, [themeObj])
React.useEffect0(() => {
if value === "" || !(options->Array.includes(value)) {
setValue(_ => options->Array.get(0)->Option.getOr(""))
if value === "" || !(options->Array.map(val => val.value)->Array.includes(value)) {
setValue(_ =>
(
options
->Array.get(0)
->Option.getOr(defaultValue)
).value
)
}
None
})
Expand All @@ -47,7 +84,7 @@ let make = (

let cursorClass = !disabled ? "cursor-pointer" : "cursor-not-allowed"
<RenderIf condition={options->Array.length > 0}>
<div className="flex flex-col w-full">
<div className={`flex flex-col ${width}`}>
<RenderIf
condition={fieldName->String.length > 0 &&
appearance.labels == Above &&
Expand All @@ -64,26 +101,42 @@ let make = (
</div>
</RenderIf>
<div className="relative">
<select
ref={dropdownRef->ReactDOM.Ref.domRef}
style={
background: disabled ? disbaledBG : themeObj.colorBackground,
opacity: disabled ? "35%" : "",
padding: themeObj.spacingUnit,
width: "100%",
}
name=""
value
disabled={readOnly || disabled}
onChange=handleChange
onFocus=handleFocus
className={`${inputClassStyles} ${className} w-full appearance-none outline-none ${cursorClass}`}>
{options
->Array.mapWithIndex((item: string, i) => {
<option key={Int.toString(i)} value=item> {React.string(item)} </option>
})
->React.array}
</select>
<div className={`Input ${className} appearance-none relative`}>
<RenderIf condition={isDisplayValueVisible && displayValue->Option.isSome}>
<div
className="absolute top-2.5 right-0 left-2 bottom-0 pointer-events-none rounded-sm"
style={
background: disabled ? disbaledBG : themeObj.colorBackground,
opacity: disabled ? "35%" : "",
padding: themeObj.spacingUnit,
width: "100%",
}>
{React.string(displayValue->Option.getOr(""))}
</div>
</RenderIf>
<select
ref={dropdownRef->ReactDOM.Ref.domRef}
style={
background: disabled ? disbaledBG : themeObj.colorBackground,
opacity: disabled ? "35%" : "",
padding: themeObj.spacingUnit,
width: "100%",
}
name=""
value
disabled={readOnly || disabled}
onChange=handleChange
onFocus=handleFocus
className={`${inputClassStyles} ${className} w-full appearance-none outline-none ${cursorClass}`}>
{options
->Array.mapWithIndex((item, index) => {
<option key={Int.toString(index)} value=item.value>
{React.string(item.label->Option.getOr(item.value))}
</option>
})
->React.array}
</select>
</div>
<RenderIf condition={config.appearance.labels == Floating}>
<div
className={`Label ${floatinglabelClass} absolute bottom-0 ml-3 ${focusClass}`}
Expand All @@ -100,7 +153,7 @@ let make = (
</div>
</RenderIf>
<div
className="self-center absolute"
className="self-center absolute pointer-events-none"
style={
opacity: disabled ? "35%" : "",
color: themeObj.colorText,
Expand Down
20 changes: 15 additions & 5 deletions src/Components/DynamicFields.res
Original file line number Diff line number Diff line change
Expand Up @@ -440,13 +440,15 @@ let make = (
/>
</div>
| Currency(currencyArr) =>
let updatedCurrencyArray =
currencyArr->DropdownField.updateArrayOfStringToOptionsTypeArray
<DropdownField
appearance=config.appearance
fieldName=localeString.currencyLabel
value=currency
setValue=setCurrency
disabled=false
options=currencyArr
options=updatedCurrencyArray
/>
| FullName =>
<>
Expand Down Expand Up @@ -560,14 +562,16 @@ let make = (
}}
</div>
| CountryAndPincode(countryArr) =>
let updatedCountryArray =
countryArr->DropdownField.updateArrayOfStringToOptionsTypeArray
<div className={`flex ${isSpacedInnerLayout ? "gap-1" : ""}`}>
<DropdownField
appearance=config.appearance
fieldName=localeString.countryLabel
value=country
setValue={setCountry}
disabled=false
options=countryArr
options=updatedCountryArray
className={isSpacedInnerLayout ? "" : "!border-t-0 !border-r-0"}
/>
<PaymentField
Expand Down Expand Up @@ -703,31 +707,37 @@ let make = (
/>
| BlikCode => <BlikCodePaymentInput />
| Country =>
let updatedCountryNames =
countryNames->DropdownField.updateArrayOfStringToOptionsTypeArray
<DropdownField
appearance=config.appearance
fieldName=localeString.countryLabel
value=country
setValue=setCountry
disabled=false
options=countryNames
options=updatedCountryNames
/>
| AddressCountry(countryArr) =>
let updatedCountryArr =
countryArr->DropdownField.updateArrayOfStringToOptionsTypeArray
<DropdownField
appearance=config.appearance
fieldName=localeString.countryLabel
value=country
setValue=setCountry
disabled=false
options=countryArr
options=updatedCountryArr
/>
| Bank =>
let updatedBankNames =
bankNames->DropdownField.updateArrayOfStringToOptionsTypeArray
<DropdownField
appearance=config.appearance
fieldName=localeString.bankLabel
value=selectedBank
setValue=setSelectedBank
disabled=false
options=bankNames
options=updatedBankNames
/>
| SpecialField(element) => element
| InfoElement =>
Expand Down
26 changes: 24 additions & 2 deletions src/Components/PaymentField.res
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ open RecoilAtomTypes
let make = (
~setValue=?,
~value: RecoilAtomTypes.field,
~valueDropDown=?,
~setValueDropDown=?,
~dropDownFieldName=?,
~dropDownOptions=?,
~onChange,
~onBlur=?,
~rightIcon=React.null,
Expand All @@ -16,6 +20,8 @@ let make = (
~placeholder="",
~className="",
~inputRef,
~displayValue=?,
~setDisplayValue=?,
) => {
let {config} = Recoil.useRecoilValueFromAtom(configAtom)
let {themeObj} = Recoil.useRecoilValueFromAtom(configAtom)
Expand Down Expand Up @@ -76,9 +82,25 @@ let make = (
}
let labelClass = getClassName("Label")
let inputClass = getClassName("Input")

let inputClassStyles = isSpacedInnerLayout ? "Input" : "Input-Compressed"

<div className="flex flex-col w-full" style={color: themeObj.colorText}>
let flexDirectionBasedOnType = type_ === "tel" ? "flex-row" : "flex-col"

<div className={`flex ${flexDirectionBasedOnType} w-full`} style={color: themeObj.colorText}>
<RenderIf condition={type_ === "tel"}>
<DropdownField
appearance=config.appearance
value={valueDropDown->Option.getOr("")}
setValue={setValueDropDown->Option.getOr(_ => ())}
fieldName={dropDownFieldName->Option.getOr("")}
options={dropDownOptions->Option.getOr([])}
width="w-1/3 mr-2"
displayValue={displayValue->Option.getOr("")}
setDisplayValue={setDisplayValue->Option.getOr(_ => ())}
isDisplayValueVisible=true
/>
</RenderIf>
<RenderIf
condition={fieldName->String.length > 0 &&
config.appearance.labels == Above &&
Expand All @@ -94,7 +116,7 @@ let make = (
{React.string(fieldName)}
</div>
</RenderIf>
<div className="flex flex-row " style={direction: direction}>
<div className="flex flex-row w-full" style={direction: direction}>
<div className="relative w-full">
<input
style={
Expand Down
91 changes: 73 additions & 18 deletions src/Components/PhoneNumberPaymentInput.res
Original file line number Diff line number Diff line change
@@ -1,37 +1,87 @@
open RecoilAtoms
open PaymentType

@react.component
let make = () => {
open RecoilAtoms
open PaymentType
open Utils

let phoneRef = React.useRef(Nullable.null)
let {fields} = Recoil.useRecoilValueFromAtom(optionAtom)
let loggerState = Recoil.useRecoilValueFromAtom(loggerAtom)

let showDetails = getShowDetails(~billingDetails=fields.billingDetails, ~logger=loggerState)
let (phone, setPhone) = Recoil.useLoggedRecoilState(userPhoneNumber, "phone", loggerState)
let clientCountry = getClientCountry(CardUtils.dateTimeFormat().resolvedOptions().timeZone)
let currentCountryCode = Utils.getCountryCode(clientCountry.countryName)
let (displayValue, setDisplayValue) = React.useState(_ => "")

let showDetails = getShowDetails(~billingDetails=fields.billingDetails, ~logger=loggerState)
let formatBSB = bsb => {
let formatted = bsb
let countryAndCodeCodeList =
phoneNumberJson
->JSON.Decode.object
->Option.getOr(Dict.make())
->getArray("countries")

let secondPart = formatted->String.sliceToEnd(~start=4)->String.trim
let phoneNumberCodeOptions: array<
DropdownField.optionType,
> = countryAndCodeCodeList->Array.reduce([], (acc, countryObj) => {
let countryObjDict = countryObj->getDictFromJson
let countryFlag = countryObjDict->getString("country_flag", "")
let phoneNumberCode = countryObjDict->getString("phone_number_code", "")
let countryName = countryObjDict->getString("country_name", "")

if formatted->String.length <= 4 {
"+351 "
} else if formatted->String.length > 4 {
`+351 ${secondPart}`
} else {
formatted
let phoneNumberOptionsValue: DropdownField.optionType = {
label: `${countryFlag} ${countryName} ${phoneNumberCode}`,
displayValue: `${countryFlag} ${phoneNumberCode}`,
value: `${countryFlag}#${phoneNumberCode}`,
}
}
acc->Array.push(phoneNumberOptionsValue)
acc
})

let defaultCountryCodeFilteredValue =
countryAndCodeCodeList
->Array.filter(countryObj => {
countryObj->getDictFromJson->getString("country_code", "") === currentCountryCode.isoAlpha2
})
->Array.get(0)
->Option.getOr(
{
"phone_number_code": "",
PritishBudhiraja marked this conversation as resolved.
Show resolved Hide resolved
}->Identity.anyTypeToJson,
)
->getDictFromJson
->getString("phone_number_code", "")

let (valueDropDown, setValueDropDown) = React.useState(_ => defaultCountryCodeFilteredValue)
let getCountryCodeSplitValue = val => val->String.split("#")->Array.get(1)->Option.getOr("")

let changePhone = ev => {
let val: string = ReactEvent.Form.target(ev)["value"]->String.replaceRegExp(%re("/\+D+/g"), "")
let val: string = ReactEvent.Form.target(ev)["value"]->String.replaceRegExp(%re("/\D|\s/g"), "")
setPhone(prev => {
...prev,
value: val->formatBSB,
countryCode: valueDropDown->getCountryCodeSplitValue,
value: val,
})
}

let phoneRef = React.useRef(Nullable.null)
React.useEffect(() => {
setPhone(prev => {
...prev,
countryCode: valueDropDown->getCountryCodeSplitValue,
})
None
}, [valueDropDown])

React.useEffect(() => {
let findDisplayValue =
phoneNumberCodeOptions
->Array.find(ele => ele.value === valueDropDown)
->Option.getOr(DropdownField.defaultValue)
setDisplayValue(_ =>
findDisplayValue.displayValue->Option.getOr(
findDisplayValue.label->Option.getOr(findDisplayValue.value),
)
)
None
}, [phoneNumberCodeOptions])

<RenderIf condition={showDetails.phone == Auto}>
<PaymentField
Expand All @@ -44,6 +94,11 @@ let make = () => {
inputRef=phoneRef
placeholder="+351 200 000 000"
maxLength=14
dropDownOptions=phoneNumberCodeOptions
valueDropDown
setValueDropDown
displayValue
setDisplayValue
/>
</RenderIf>
}
Loading
Loading