|
1 | | -import { FC } from 'react'; |
2 | | -import { useFormContext } from 'react-hook-form'; |
| 1 | +import { Autocomplete, Box, Checkbox, FormControlLabel, TextField } from '@mui/material'; |
| 2 | +import { FC, useEffect, useMemo } from 'react'; |
| 3 | +import { Controller, useFormContext } from 'react-hook-form'; |
3 | 4 | import { FormSelect, FormTextField } from 'src/components/form'; |
4 | 5 | import InputMask from 'src/components/InputMask'; |
5 | 6 | import { Row, Section } from 'src/components/layout'; |
6 | | -import { EMERGENCY_CONTACT_RELATIONSHIP_OPTIONS, FormFields as AllFormFields } from 'src/constants'; |
7 | | -import { isPhoneNumberValid, REQUIRED_FIELD_ERROR_MESSAGE } from 'utils'; |
| 7 | +import { |
| 8 | + EMERGENCY_CONTACT_RELATIONSHIP_OPTIONS, |
| 9 | + FormFields as AllFormFields, |
| 10 | + PatientAddressFields, |
| 11 | + STATE_OPTIONS, |
| 12 | +} from 'src/constants'; |
| 13 | +import { isPhoneNumberValid, isPostalCodeValid, REQUIRED_FIELD_ERROR_MESSAGE } from 'utils'; |
8 | 14 |
|
9 | | -const FormFields = AllFormFields.emergencyContact; |
| 15 | +const { emergencyContact: FormFields } = AllFormFields; |
10 | 16 |
|
11 | 17 | export const EmergencyContactContainer: FC<{ isLoading: boolean }> = ({ isLoading }) => { |
12 | | - const { control } = useFormContext(); |
| 18 | + const { control, watch, setValue } = useFormContext(); |
| 19 | + |
| 20 | + const emergencyAddressFields = useMemo( |
| 21 | + () => [ |
| 22 | + FormFields.streetAddress.key, |
| 23 | + FormFields.addressLine2.key, |
| 24 | + FormFields.city.key, |
| 25 | + FormFields.state.key, |
| 26 | + FormFields.zip.key, |
| 27 | + ], |
| 28 | + [] |
| 29 | + ); |
| 30 | + |
| 31 | + const patientAddressData = watch(PatientAddressFields); |
| 32 | + const emergencyAddressData = watch(emergencyAddressFields); |
| 33 | + const sameAsPatientAddress = watch(FormFields.addressAsPatient.key, false); |
| 34 | + |
| 35 | + useEffect(() => { |
| 36 | + if (!sameAsPatientAddress) return; |
| 37 | + for (let i = 0; i < emergencyAddressData.length; i++) { |
| 38 | + if (patientAddressData[i] && emergencyAddressData[i] !== patientAddressData[i]) { |
| 39 | + setValue(emergencyAddressFields[i], patientAddressData[i]); |
| 40 | + } |
| 41 | + } |
| 42 | + }, [emergencyAddressData, emergencyAddressFields, patientAddressData, sameAsPatientAddress, setValue]); |
13 | 43 |
|
14 | 44 | return ( |
15 | 45 | <Section title="Emergency contact information"> |
@@ -75,6 +105,79 @@ export const EmergencyContactContainer: FC<{ isLoading: boolean }> = ({ isLoadin |
75 | 105 | disabled={isLoading} |
76 | 106 | /> |
77 | 107 | </Row> |
| 108 | + <Row label=" "> |
| 109 | + <Controller |
| 110 | + name={FormFields.addressAsPatient.key} |
| 111 | + control={control} |
| 112 | + render={({ field: { value, ...field } }) => ( |
| 113 | + <FormControlLabel |
| 114 | + control={ |
| 115 | + <Checkbox |
| 116 | + {...field} |
| 117 | + checked={value ?? false} |
| 118 | + onChange={(e) => field.onChange(e.target.checked)} |
| 119 | + disabled={isLoading} |
| 120 | + /> |
| 121 | + } |
| 122 | + label={FormFields.addressAsPatient.label} |
| 123 | + /> |
| 124 | + )} |
| 125 | + /> |
| 126 | + </Row> |
| 127 | + <Row label={FormFields.streetAddress.label} inputId={FormFields.streetAddress.key}> |
| 128 | + <FormTextField |
| 129 | + name={FormFields.streetAddress.key} |
| 130 | + control={control} |
| 131 | + id={FormFields.streetAddress.key} |
| 132 | + disabled={isLoading || (sameAsPatientAddress && Boolean(patientAddressData[0]))} |
| 133 | + /> |
| 134 | + </Row> |
| 135 | + <Row label={FormFields.addressLine2.label} inputId={FormFields.addressLine2.key}> |
| 136 | + <FormTextField |
| 137 | + name={FormFields.addressLine2.key} |
| 138 | + control={control} |
| 139 | + id={FormFields.addressLine2.key} |
| 140 | + disabled={isLoading || sameAsPatientAddress} |
| 141 | + /> |
| 142 | + </Row> |
| 143 | + <Row label="City, State, ZIP"> |
| 144 | + <Box sx={{ display: 'flex', gap: 2 }}> |
| 145 | + <FormTextField |
| 146 | + name={FormFields.city.key} |
| 147 | + control={control} |
| 148 | + disabled={isLoading || (sameAsPatientAddress && Boolean(patientAddressData[2]))} |
| 149 | + /> |
| 150 | + <Controller |
| 151 | + name={FormFields.state.key} |
| 152 | + control={control} |
| 153 | + render={({ field: { value }, fieldState: { error } }) => ( |
| 154 | + <Autocomplete |
| 155 | + options={STATE_OPTIONS.map((option) => option.value)} |
| 156 | + value={value ?? ''} |
| 157 | + onChange={(_, newValue) => { |
| 158 | + setValue(FormFields.state.key, newValue ?? ''); |
| 159 | + }} |
| 160 | + fullWidth |
| 161 | + renderInput={(params) => ( |
| 162 | + <TextField {...params} variant="standard" error={!!error} helperText={error?.message} /> |
| 163 | + )} |
| 164 | + disabled={isLoading || (sameAsPatientAddress && Boolean(patientAddressData[3]))} |
| 165 | + /> |
| 166 | + )} |
| 167 | + /> |
| 168 | + <FormTextField |
| 169 | + name={FormFields.zip.key} |
| 170 | + control={control} |
| 171 | + rules={{ |
| 172 | + validate: (value: string) => { |
| 173 | + if (!value) return true; |
| 174 | + return isPostalCodeValid(value) || 'Must be 5 digits'; |
| 175 | + }, |
| 176 | + }} |
| 177 | + disabled={isLoading || (sameAsPatientAddress && Boolean(patientAddressData[4]))} |
| 178 | + /> |
| 179 | + </Box> |
| 180 | + </Row> |
78 | 181 | </Section> |
79 | 182 | ); |
80 | 183 | }; |
0 commit comments