Skip to content

Commit 9ac9a5e

Browse files
fix: added setAreRequiredFieldsEmpty message support, refactored GenericInput and Dob component to use useField
1 parent 18571ee commit 9ac9a5e

3 files changed

Lines changed: 115 additions & 99 deletions

File tree

src/Components/DynamicFields.res

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ let make = (
178178
let spacedStylesForBillingDetails = isSpacedInnerLayout ? "p-2" : "my-2"
179179
let hasAnyField = missingRequiredFieldsFiltered->Array.length > 0
180180
let setAreRequiredFieldsValid = Recoil.useSetRecoilState(areRequiredFieldsValid)
181+
let setAreRequiredFieldsEmpty = Recoil.useSetRecoilState(areRequiredFieldsEmpty)
182+
183+
React.useEffect(() => {
184+
if isSavedCardFlow || !hasAnyField {
185+
setAreRequiredFieldsValid(_ => true)
186+
setAreRequiredFieldsEmpty(_ => false)
187+
}
188+
None
189+
}, (isSavedCardFlow, hasAnyField))
181190

182191
<>
183192
<RenderIf condition={!isSavedCardFlow && hasAnyField}>
@@ -192,6 +201,15 @@ let make = (
192201
// RFF stores values as nested objects; flatten to dot-notation keys so they align with the confirm-payload merge.
193202
let flatValues = values->JSON.Encode.object->Utils.flattenObject(false)
194203
setRequiredFieldsBody(_ => flatValues)
204+
205+
let isEmpty = missingRequiredFieldsFiltered->Array.some(field => {
206+
switch flatValues->Dict.get(field.confirmRequestWritePath) {
207+
| None | Some(JSON.Null) => true
208+
| Some(JSON.String(str)) => str->String.trim === ""
209+
| Some(_) => false
210+
}
211+
})
212+
setAreRequiredFieldsEmpty(_ => isEmpty)
195213
},
196214
~onValidationChange=isValid => {
197215
setAreRequiredFieldsValid(_ => isValid)

src/Components/DynamicFields/GenericInputField.res

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ let make = (~fieldConfig: fieldConfig) => {
1111
let autocomplete = fieldConfig.htmlAutocompleteAttribute
1212
let validate = DynamicFieldsUtils.resolveValidator(~field=fieldConfig, ~localeObject=localeString)
1313

14-
<ReactFinalForm.Field name={fieldConfig.confirmRequestWritePath} validate={Some(validate)}>
15-
{(fieldProps: ReactFinalForm.Field.fieldProps) => {
16-
let {input, meta} = fieldProps
17-
let value = input.value->Option.getOr("")
18-
let showError = meta.touched || meta.submitFailed
19-
let isValid = showError ? Some(meta.valid) : None
20-
let errorString = showError && meta.invalid ? meta.error->Option.getOr("") : ""
21-
<PaymentInputField
22-
fieldName={label}
23-
value
24-
onChange={ev => input.onChange(ReactEvent.Form.target(ev)["value"])}
25-
onBlur={_ev => input.onBlur()}
26-
isValid
27-
errorString
28-
placeholder
29-
inputRef={fieldRef}
30-
?autocomplete
31-
maxLength=?{fieldConfig.maxInputLength}
32-
/>
33-
}}
34-
</ReactFinalForm.Field>
14+
let {input, meta} = ReactFinalForm.useField(
15+
fieldConfig.confirmRequestWritePath,
16+
~config={validate: validate},
17+
)
18+
let value = input.value->Option.getOr("")
19+
let showError = meta.touched || meta.submitFailed
20+
let isValid = showError ? Some(meta.valid) : None
21+
let errorString = showError && meta.invalid ? meta.error->Option.getOr("") : ""
22+
23+
<PaymentInputField
24+
fieldName={label}
25+
value
26+
onChange={ev => input.onChange(ReactEvent.Form.target(ev)["value"])}
27+
onBlur={_ev => input.onBlur()}
28+
isValid
29+
errorString
30+
placeholder
31+
inputRef={fieldRef}
32+
?autocomplete
33+
maxLength=?{fieldConfig.maxInputLength}
34+
/>
3535
}

src/Payments/DateOfBirth.res

Lines changed: 76 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -32,84 +32,82 @@ let make = (~fieldConfig: SuperpositionTypes.fieldConfig) => {
3232

3333
let validate = DynamicFieldsUtils.resolveValidator(~field=fieldConfig, ~localeObject=localeString)
3434

35-
<ReactFinalForm.Field name={path} validate={Some(validate)}>
36-
{(field: ReactFinalForm.Field.fieldProps) => {
37-
let touched = field.meta.touched
38-
let invalid = field.meta.invalid
39-
<div className="flex flex-col gap-1">
40-
<div
41-
className={`Label`}
42-
style={
43-
fontWeight: themeObj.fontWeightNormal,
44-
fontSize: themeObj.fontSizeLg,
45-
opacity: "0.6",
46-
}>
47-
{label->React.string}
35+
let field = ReactFinalForm.useField(path, ~config={validate: validate})
36+
let touched = field.meta.touched
37+
let invalid = field.meta.invalid
38+
39+
<div className="flex flex-col gap-1">
40+
<div
41+
className={`Label`}
42+
style={
43+
fontWeight: themeObj.fontWeightNormal,
44+
fontSize: themeObj.fontSizeLg,
45+
opacity: "0.6",
46+
}>
47+
{label->React.string}
48+
</div>
49+
<DatePicker
50+
showIcon=true
51+
icon={<Icon name="calander" size=13 className="!px-[6px] !py-[10px]" />}
52+
className="w-full border border-gray-300 rounded p-2"
53+
selected={selectedDate}
54+
onChange={date => {
55+
setSelectedDate(_ => date)
56+
let strVal =
57+
date
58+
->Nullable.toOption
59+
->Option.map(d => d->Date.toLocaleDateStringWithLocale("en-CA"))
60+
->Option.getOr("")
61+
field.input.onChange(strVal)
62+
}}
63+
dateFormat
64+
wrapperClassName="datepicker"
65+
shouldCloseOnSelect=true
66+
placeholderText={placeholder}
67+
renderCustomHeader={val => {
68+
<div className="flex gap-4 items-center justify-center m-2">
69+
<select
70+
className="p-1"
71+
value={val.date->Date.getFullYear->Int.toString}
72+
onChange={ev => {
73+
let value = {ev->ReactEvent.Form.target}["value"]
74+
val.changeYear(value)
75+
}}>
76+
{years
77+
->Array.map(option =>
78+
<option key={option->Int.toString} value={option->Int.toString}>
79+
{option->React.int}
80+
</option>
81+
)
82+
->React.array}
83+
</select>
84+
<select
85+
className="p-1"
86+
value={months[val.date->Date.getMonth]->Option.getOr("January")}
87+
onChange={ev => {
88+
let value = {ev->ReactEvent.Form.target}["value"]
89+
val.changeMonth(months->Array.indexOf(value))
90+
}}>
91+
{months
92+
->Array.map(option =>
93+
<option key={option} value={option}> {option->React.string} </option>
94+
)
95+
->React.array}
96+
</select>
4897
</div>
49-
<DatePicker
50-
showIcon=true
51-
icon={<Icon name="calander" size=13 className="!px-[6px] !py-[10px]" />}
52-
className="w-full border border-gray-300 rounded p-2"
53-
selected={selectedDate}
54-
onChange={date => {
55-
setSelectedDate(_ => date)
56-
let strVal =
57-
date
58-
->Nullable.toOption
59-
->Option.map(d => d->Date.toLocaleDateStringWithLocale("en-CA"))
60-
->Option.getOr("")
61-
field.input.onChange(strVal)
62-
}}
63-
dateFormat
64-
wrapperClassName="datepicker"
65-
shouldCloseOnSelect=true
66-
placeholderText={placeholder}
67-
renderCustomHeader={val => {
68-
<div className="flex gap-4 items-center justify-center m-2">
69-
<select
70-
className="p-1"
71-
value={val.date->Date.getFullYear->Int.toString}
72-
onChange={ev => {
73-
let value = {ev->ReactEvent.Form.target}["value"]
74-
val.changeYear(value)
75-
}}>
76-
{years
77-
->Array.map(option =>
78-
<option key={option->Int.toString} value={option->Int.toString}>
79-
{option->React.int}
80-
</option>
81-
)
82-
->React.array}
83-
</select>
84-
<select
85-
className="p-1"
86-
value={months[val.date->Date.getMonth]->Option.getOr("January")}
87-
onChange={ev => {
88-
let value = {ev->ReactEvent.Form.target}["value"]
89-
val.changeMonth(months->Array.indexOf(value))
90-
}}>
91-
{months
92-
->Array.map(option =>
93-
<option key={option} value={option}> {option->React.string} </option>
94-
)
95-
->React.array}
96-
</select>
97-
</div>
98-
}}
99-
/>
100-
<RenderIf condition={touched && invalid}>
101-
<div
102-
className="Error pt-1"
103-
style={
104-
color: themeObj.colorDangerText,
105-
fontSize: themeObj.fontSizeSm,
106-
alignSelf: "start",
107-
textAlign: "left",
108-
}>
109-
{field.meta.error->Option.getOr("")->React.string}
110-
</div>
111-
</RenderIf>
98+
}}
99+
/>
100+
<RenderIf condition={touched && invalid}>
101+
<div
102+
className="Error pt-1"
103+
style={
104+
color: themeObj.colorDangerText,
105+
fontSize: themeObj.fontSizeSm,
106+
alignSelf: "start",
107+
textAlign: "left",
108+
}>
109+
{field.meta.error->Option.getOr("")->React.string}
112110
</div>
113-
}}
114-
</ReactFinalForm.Field>
111+
</RenderIf>
112+
</div>
115113
}

0 commit comments

Comments
 (0)