Skip to content

Commit

Permalink
fix: date of birth validations (#480)
Browse files Browse the repository at this point in the history
Co-authored-by: vsrivatsa-juspay <[email protected]>
  • Loading branch information
PritishBudhiraja and vsrivatsa-juspay authored Jul 9, 2024
1 parent c56b0fe commit 8d9c620
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 20 deletions.
45 changes: 44 additions & 1 deletion src/Payments/DateOfBirth.res
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,37 @@ let years = Array.fromInitializer(~length=currentYear - startYear, i => currentY

@react.component
let make = () => {
open Utils
let {themeObj, localeString} = Recoil.useRecoilValueFromAtom(RecoilAtoms.configAtom)
let (selectedDate, setSelectedDate) = Recoil.useRecoilState(RecoilAtoms.dateOfBirth)
let (error, setError) = React.useState(_ => false)
let isNotEligible = React.useMemo(() => {
let isAbove18 = switch selectedDate->Nullable.toOption {
| Some(val) => val->checkIs18OrAbove
| None => false
}
!isAbove18
}, [selectedDate])

let submitCallback = React.useCallback((ev: Window.event) => {
let json = ev.data->JSON.parseExn
let confirm = json->getDictFromJson->ConfirmType.itemToObjMapper
if confirm.doSubmit {
switch selectedDate->Nullable.toOption {
| Some(_) => setError(_ => false)
| None => ()
}
}
}, (selectedDate, isNotEligible))

useSubmitPaymentData(submitCallback)

let onChange = date => {
setSelectedDate(_ => date)
}
let errorString = error
? "Date of birth is required"
: "Age should be equal or greater than 18 years"

<div className="flex flex-col gap-1">
<div
Expand All @@ -39,9 +68,11 @@ let make = () => {
icon={<Icon name="calander" size=13 className="!px-[6px] !py-[10px]" />}
className="w-full border border-gray-300 rounded p-2"
selected={selectedDate}
onChange={date => setSelectedDate(_ => date)}
onChange={date => onChange(date)}
dateFormat="dd-MM-yyyy"
wrapperClassName="datepicker"
shouldCloseOnSelect=true
placeholderText="Enter Date of Birth"
renderCustomHeader={val => {
<div className="flex gap-4 items-center justify-center m-2">
<select
Expand Down Expand Up @@ -75,5 +106,17 @@ let make = () => {
</div>
}}
/>
<RenderIf condition={error || isNotEligible}>
<div
className="Error pt-1"
style={
color: themeObj.colorDangerText,
fontSize: themeObj.fontSizeSm,
alignSelf: "start",
textAlign: "left",
}>
{React.string(errorString)}
</div>
</RenderIf>
</div>
}
22 changes: 19 additions & 3 deletions src/Utilities/DynamicFieldsUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ let useRequiredFieldsEmptyAndValid = (
let setAreRequiredFieldsEmpty = Recoil.useSetRecoilState(areRequiredFieldsEmpty)
let {billingAddress} = Recoil.useRecoilValueFromAtom(optionAtom)
let cryptoCurrencyNetworks = Recoil.useRecoilValueFromAtom(cryptoCurrencyNetworks)
let dateOfBirth = Recoil.useRecoilValueFromAtom(dateOfBirth)

let fieldsArrWithBillingAddress = fieldsArr->addBillingAddressIfUseBillingAddress(billingAddress)

Expand Down Expand Up @@ -159,6 +160,11 @@ let useRequiredFieldsEmptyAndValid = (
isExpiryValid->Option.getOr(false)
| CardCvc => isCVCValid->Option.getOr(false)
| CardExpiryAndCvc => isExpiryValid->Option.getOr(false) && isCVCValid->Option.getOr(false)
| DateOfBirth =>
switch dateOfBirth->Nullable.toOption {
| Some(val) => val->Utils.checkIs18OrAbove
| None => false
}
| _ => true
}
})
Expand Down Expand Up @@ -203,6 +209,7 @@ let useRequiredFieldsEmptyAndValid = (
| CardExpiryAndCvc =>
let (month, year) = getExpiryDates(cardExpiry)
month === "" || year === "" || cvcNumber === ""
| DateOfBirth => dateOfBirth->Js.Nullable.isNullable
| _ => false
}
})
Expand All @@ -215,6 +222,7 @@ let useRequiredFieldsEmptyAndValid = (
country,
billingName.value,
line1.value,
dateOfBirth,
(
email,
line2.value,
Expand Down Expand Up @@ -382,8 +390,12 @@ let useSetInitialRequiredFields = (
setCryptoCurrencyNetworks(_ => value)
}
| DateOfBirth =>
if value !== "" && dateOfBirth->Date.toDateString === "" {
setDateOfBirth(_ => dateOfBirth)
switch dateOfBirth->Nullable.toOption {
| Some(x) =>
if value !== "" && x->Date.toDateString === "" {
setDateOfBirth(_ => Nullable.make(x))
}
| None => ()
}
| SpecialField(_)
| InfoElement
Expand Down Expand Up @@ -470,7 +482,11 @@ let useRequiredFieldsBody = (
let (_, year) = CardUtils.getExpiryDates(cardExpiry)
year
| CryptoCurrencyNetworks => cryptoCurrencyNetworks
| DateOfBirth => dateOfBirth->Date.toISOString->String.slice(~start=0, ~end=10)
| DateOfBirth =>
switch dateOfBirth->Nullable.toOption {
| Some(x) => x->Date.toISOString->String.slice(~start=0, ~end=10)
| None => ""
}
| CardCvc => cvcNumber
| StateAndCity
| CountryAndPincode(_)
Expand Down
2 changes: 1 addition & 1 deletion src/Utilities/PaymentHelpers.res
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ let retrieveStatus = (~headers, ~switchToCustomPod, pollID, logger) => {
~optLogger=Some(logger),
~url=uri,
~apiLogType=Request,
~eventName=POLL_STATUS_INIT,
~eventName=POLL_STATUS_CALL_INIT,
~logType=INFO,
~logCategory=API,
(),
Expand Down
2 changes: 1 addition & 1 deletion src/Utilities/RecoilAtoms.res
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ let cryptoCurrencyNetworks = Recoil.atom("cryptoCurrencyNetworks", "")
let isShowOrPayUsing = Recoil.atom("isShowOrPayUsing", false)
let areRequiredFieldsValid = Recoil.atom("areRequiredFieldsValid", true)
let areRequiredFieldsEmpty = Recoil.atom("areRequiredFieldsEmpty", false)
let dateOfBirth = Recoil.atom("dateOfBirth", Date.make())
let dateOfBirth = Recoil.atom("dateOfBirth", Nullable.null)
let userBillingName = Recoil.atom("userBillingName", defaultFieldValues)

type areOneClickWalletsRendered = {
Expand Down
9 changes: 9 additions & 0 deletions src/Utilities/Utils.res
Original file line number Diff line number Diff line change
Expand Up @@ -1341,3 +1341,12 @@ let handleFailureResponse = (~message, ~errorType) =>

let getPaymentId = clientSecret =>
String.split(clientSecret, "_secret_")->Array.get(0)->Option.getOr("")

let checkIs18OrAbove = dateOfBirth => {
let currentDate = Date.make()
let year = currentDate->Date.getFullYear - 18
let month = currentDate->Date.getMonth
let date = currentDate->Date.getDate
let compareDate = Date.makeWithYMD(~year, ~month, ~date)
dateOfBirth <= compareDate
}
5 changes: 3 additions & 2 deletions src/libraries/DatePicker.res
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ type customHeaderProps = {

@module("react-datepicker") @react.component
external make: (
~selected: Date.t,
~onChange: Date.t => unit,
~selected: Nullable.t<Date.t>,
~onChange: Nullable.t<Date.t> => unit,
~showIcon: bool=?,
~icon: React.element=?,
~dateFormat: string=?,
Expand All @@ -31,4 +31,5 @@ external make: (
~className: string=?,
~wrapperClassName: string=?,
~closeOnScroll: bool=?,
~shouldCloseOnSelect: bool=?,
) => React.element = "default"
15 changes: 3 additions & 12 deletions src/orca-log-catcher/OrcaLogger.res
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type eventName =
| PAYMENT_METHODS_RESPONSE
| LOADER_CHANGED
| PAYMENT_SESSION_INITIATED
| POLL_STATUS_INIT
| POLL_STATUS_CALL_INIT
| POLL_STATUS_CALL
| COMPLETE_AUTHORIZE_CALL_INIT
| COMPLETE_AUTHORIZE_CALL
Expand Down Expand Up @@ -151,7 +151,7 @@ let eventNameToStrMapper = eventName => {
| PAYMENT_METHODS_RESPONSE => "PAYMENT_METHODS_RESPONSE"
| LOADER_CHANGED => "LOADER_CHANGED"
| PAYMENT_SESSION_INITIATED => "PAYMENT_SESSION_INITIATED"
| POLL_STATUS_INIT => "POLL_STATUS_INIT"
| POLL_STATUS_CALL_INIT => "POLL_STATUS_CALL_INIT"
| POLL_STATUS_CALL => "POLL_STATUS_CALL"
| COMPLETE_AUTHORIZE_CALL_INIT => "COMPLETE_AUTHORIZE_CALL_INIT"
| COMPLETE_AUTHORIZE_CALL => "COMPLETE_AUTHORIZE_CALL"
Expand Down Expand Up @@ -649,15 +649,7 @@ let make = (
| _ => 0.
}
}
| AUTHENTICATION_CALL
| RETRIEVE_CALL
| CONFIRM_CALL
| SESSIONS_CALL
| PAYMENT_METHODS_CALL
| CUSTOMER_PAYMENT_METHODS_CALL
| PAYMENT_METHODS_AUTH_EXCHANGE_CALL
| PAYMENT_METHODS_AUTH_LINK_CALL
| CREATE_CUSTOMER_PAYMENT_METHODS_CALL => {
| _ => {
let logRequestTimestamp =
events.contents->Dict.get(eventName->eventNameToStrMapper ++ "_INIT")
switch (logRequestTimestamp, apiLogType) {
Expand All @@ -666,7 +658,6 @@ let make = (
| _ => 0.
}
}
| _ => 0.
}
latency > 0. ? latency->Float.toString : ""
}
Expand Down

0 comments on commit 8d9c620

Please sign in to comment.