+
+ Child
+
+
+ e !== '')}
+ value={childName}
+ isDisabled={isSubmitting}
+ initialIsOpen={!!myInfoChildrenBirthRecords?.childname}
+ onChange={(name) => {
+ // This is bad practice but we have no choice because our
+ // custom Select doesn't forward the event.
+ setValue(childNamePath, name)
+ }}
+ />
+
+ }
+ aria-label="Remove child"
+ alignSelf="end"
+ disabled={fields.length <= 1}
+ onClick={() => {
+ if (fields.length > 1) {
+ remove(fields.length - 1)
+ }
+ }}
+ />
+
+
+ {schema.childrenSubFields
+ ?.filter((subField) => subField !== MyInfoChildAttributes.ChildName)
+ .map((subField, index) => {
+ // First index taken by name.
+ index += 1
+ const key = `${field.id}+${index}`
+ const fieldPath = `${schema._id}.child.${currChildBodyIdx}.${index}`
+ const myInfoValue = getChildAttr(subField)
+ const value = watch(fieldPath) as unknown as string
+ if (myInfoValue && value !== myInfoValue) {
+ // We need to do this as the underlying data is not updated
+ // by the field's value, but rather by onChange, which we did
+ // not trigger via prefill.
+ setValue(fieldPath, myInfoValue)
+ }
+ const isDisabled = isSubmitting || !!myInfoValue
+ switch (subField) {
+ case MyInfoChildAttributes.ChildBirthCertNo: {
+ return (
+
+
+ {MYINFO_ATTRIBUTE_MAP[subField].description}
+
+
+
+ )
+ }
+ case MyInfoChildAttributes.ChildVaxxStatus:
+ case MyInfoChildAttributes.ChildGender:
+ case MyInfoChildAttributes.ChildRace:
+ case MyInfoChildAttributes.ChildSecondaryRace: {
+ return (
+
+
+ {MYINFO_ATTRIBUTE_MAP[subField].description}
+
+
+ // This is bad practice but we have no choice because our
+ // custom Select doesn't forward the event.
+ setValue(fieldPath, option)
+ }
+ />
+
+ )
+ }
+ case MyInfoChildAttributes.ChildDateOfBirth: {
+ const { onChange, ...rest } = register(fieldPath, validationRules)
+ return (
+
+
+ {MYINFO_ATTRIBUTE_MAP[subField].description}
+
+ {
+ setValue(fieldPath, date)
+ }}
+ colorScheme={`theme-${colorTheme}`}
+ />
+
+ )
+ }
+ default:
+ return Unsupported child subfield
+ }
+ })}
+ {/* No divider on last child */}
+ {currChildBodyIdx < fields.length - 1 ? (
+ <>
+
+
+
+ >
+ ) : null}
+
+ )
+}
diff --git a/frontend/src/templates/Field/ChildrenCompound/index.ts b/frontend/src/templates/Field/ChildrenCompound/index.ts
new file mode 100644
index 0000000000..9f6c8b7c7a
--- /dev/null
+++ b/frontend/src/templates/Field/ChildrenCompound/index.ts
@@ -0,0 +1 @@
+export { ChildrenCompoundField as default } from './ChildrenCompoundField'
diff --git a/frontend/src/templates/Field/index.ts b/frontend/src/templates/Field/index.ts
index 189a611c39..154c16276a 100644
--- a/frontend/src/templates/Field/index.ts
+++ b/frontend/src/templates/Field/index.ts
@@ -1,5 +1,6 @@
import AttachmentField from './Attachment'
import CheckboxField from './Checkbox'
+import ChildrenCompoundField from './ChildrenCompound'
import DateField from './Date'
import DecimalField from './Decimal'
import DropdownField from './Dropdown'
@@ -24,6 +25,7 @@ export * from './types'
export {
AttachmentField,
CheckboxField,
+ ChildrenCompoundField,
DateField,
DecimalField,
DropdownField,
diff --git a/frontend/src/templates/Field/types.ts b/frontend/src/templates/Field/types.ts
index cf1ffeccf5..c686f7e789 100644
--- a/frontend/src/templates/Field/types.ts
+++ b/frontend/src/templates/Field/types.ts
@@ -14,6 +14,7 @@ import {
ImageFieldBase,
LongTextFieldBase,
MobileFieldBase,
+ MyInfoChildAttributes,
NricFieldBase,
NumberFieldBase,
RadioFieldBase,
@@ -25,6 +26,7 @@ import {
UenFieldBase,
YesNoFieldBase,
} from '~shared/types/field'
+import { ChildrenCompoundFieldBase } from '~shared/types/field/childrenCompoundField'
import {
SingleAnswerResponse,
VerifiableResponseBase,
@@ -56,6 +58,8 @@ export type TableFieldInputs = FieldInput