Skip to content

Commit 2ca187f

Browse files
committed
testing
1 parent cc68866 commit 2ca187f

24 files changed

+3834
-170
lines changed

apps/ehr/src/constants/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,16 @@ export const FormFields = {
644644
middleName: { key: 'emergency-contact-middle-name', type: 'String', label: 'Middle name' },
645645
lastName: { key: 'emergency-contact-last-name', type: 'String', label: 'Last name' },
646646
phone: { key: 'emergency-contact-number', type: 'String', label: 'Phone' },
647+
addressAsPatient: {
648+
key: 'emergency-contact-address-as-patient',
649+
type: 'Boolean',
650+
label: "Emergency contact address is the same as patient's address",
651+
},
652+
streetAddress: { key: 'emergency-contact-address', type: 'String', label: 'Street address' },
653+
addressLine2: { key: 'emergency-contact-address-2', type: 'String', label: 'Address line 2 (optional)' },
654+
city: { key: 'emergency-contact-city', type: 'String', label: 'City' },
655+
state: { key: 'emergency-contact-state', type: 'String', label: 'State' },
656+
zip: { key: 'emergency-contact-zip', type: 'String', label: 'Zip' },
647657
},
648658
preferredPharmacy: {
649659
name: { key: 'pharmacy-name', type: 'String', label: 'Pharmacy name' },

apps/ehr/src/features/visits/shared/components/patient/EmergencyContactContainer.tsx

Lines changed: 109 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,45 @@
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';
34
import { FormSelect, FormTextField } from 'src/components/form';
45
import InputMask from 'src/components/InputMask';
56
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';
814

9-
const FormFields = AllFormFields.emergencyContact;
15+
const { emergencyContact: FormFields } = AllFormFields;
1016

1117
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]);
1343

1444
return (
1545
<Section title="Emergency contact information">
@@ -75,6 +105,79 @@ export const EmergencyContactContainer: FC<{ isLoading: boolean }> = ({ isLoadin
75105
disabled={isLoading}
76106
/>
77107
</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>
78181
</Section>
79182
);
80183
};

apps/ehr/tests/e2e-utils/seed-data/seed-ehr-appointment-data.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,49 @@
15091509
"valueString": "(123) 123-1234"
15101510
}
15111511
]
1512+
},
1513+
{
1514+
"linkId": "emergency-contact-address-as-patient"
1515+
},
1516+
{
1517+
"linkId": "emergency-contact-address",
1518+
"answer": [
1519+
{
1520+
"valueString": "address"
1521+
}
1522+
]
1523+
},
1524+
{
1525+
"linkId": "emergency-contact-address-2",
1526+
"answer": [
1527+
{
1528+
"valueString": "address 2"
1529+
}
1530+
]
1531+
},
1532+
{
1533+
"linkId": "emergency-contact-city",
1534+
"answer": [
1535+
{
1536+
"valueString": "city"
1537+
}
1538+
]
1539+
},
1540+
{
1541+
"linkId": "emergency-contact-state",
1542+
"answer": [
1543+
{
1544+
"valueString": "AL"
1545+
}
1546+
]
1547+
},
1548+
{
1549+
"linkId": "emergency-contact-zip",
1550+
"answer": [
1551+
{
1552+
"valueString": "12312"
1553+
}
1554+
]
15121555
}
15131556
]
15141557
},

apps/intake/src/features/paperwork/components/AIInterview.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ const AIInterview: FC<AIInterviewProps> = ({ value: medicalHistoryInterviewCompl
3838
}, [aiInterviewQuestionnaireResponse, setAiInterviewQuestionnaireResponse, zambdaClient, appointmentId]);
3939

4040
useEffect(() => {
41+
if (!setContinueLabel) {
42+
return;
43+
}
4144
if (aiInterviewQuestionnaireResponse?.status === 'completed') {
4245
setContinueLabel(undefined);
4346
} else {

apps/intake/src/features/paperwork/context/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export interface PaperworkContext
2323
paymentMethodStateInitializing: boolean;
2424
paymentMethods: CreditCardInfo[];
2525
stripeSetupData: string | undefined;
26-
setContinueLabel: (label: string | undefined) => void;
26+
setContinueLabel?: (label: string | undefined) => void;
2727
saveButtonDisabled?: boolean;
2828
refetchPaymentMethods: (options?: RefetchOptions | undefined) => Promise<
2929
QueryObserverResult<

apps/intake/src/pages/PaperworkPage.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,9 @@ export const PaperworkPage: FC = () => {
386386
const [loading, setLoading] = useState<boolean>(false);
387387
// when the page changes, update continue label
388388
useEffect(() => {
389+
if (!setContinueLabel) {
390+
return;
391+
}
389392
setContinueLabel(undefined);
390393
}, [setContinueLabel, pageName]);
391394

apps/intake/src/pages/PatientInformation.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ export const PatientInfoCollection: FC = () => {
114114
paymentMethods: [],
115115
paymentMethodStateInitializing: false,
116116
stripeSetupData: undefined,
117+
setContinueLabel: undefined,
117118
refetchPaymentMethods: () => {
118119
throw new Error('Function not implemented.');
119120
},

apps/intake/tests/utils/Paperwork.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ interface EmergencyContact {
6060
firstName: string;
6161
lastName: string;
6262
phone: string;
63+
address: string;
64+
addressLine2: string;
65+
city: string;
66+
state: string;
67+
zip: string;
6368
}
6469

6570
interface TelemedPaperworkData {
@@ -893,15 +898,22 @@ export class Paperwork {
893898
firstName: string;
894899
lastName: string;
895900
phone: string;
901+
address: string;
902+
addressLine2: string;
903+
city: string;
904+
state: string;
905+
zip: string;
896906
}> {
897907
const { relationship } = await this.fillEmergencyContactInformationRelationship();
898908
const name = await this.fillEmergencyContactInformationName();
899909
const { formattedPhoneNumber: phone } = await this.fillEmergencyContactInformationPhone();
910+
const addressInfo = await this.fillEmergencyContactAddressInformation();
900911
return {
901912
relationship,
902913
firstName: name.firstName,
903914
lastName: name.lastName,
904915
phone,
916+
...addressInfo,
905917
};
906918
}
907919
async fillEmergencyContactInformationRelationship(): Promise<{ relationship: string }> {
@@ -928,6 +940,28 @@ export class Paperwork {
928940
await this.locator.emergencyContactInformationPhone.fill(PHONE_NUMBER);
929941
return { formattedPhoneNumber };
930942
}
943+
async fillEmergencyContactAddressInformation(): Promise<{
944+
address: string;
945+
addressLine2: string;
946+
city: string;
947+
state: string;
948+
zip: string;
949+
}> {
950+
await this.locator.emergencyContactSameAddressAsPatient.setChecked(false);
951+
const address = `Emergency Address ${this.getRandomString()}`;
952+
const addressLine2 = `Emergency Address Line 2 ${this.getRandomString()}`;
953+
const city = `EmergencyCity${this.getRandomString()}`;
954+
const state = 'AL';
955+
const zip = '12345';
956+
await this.locator.emergencyContactAddress.fill(address);
957+
await this.locator.emergencyContactAddressLine2.fill(addressLine2);
958+
await this.locator.emergencyContactCity.fill(city);
959+
await this.locator.emergencyContactState.click();
960+
await this.page.getByRole('option').first().click();
961+
await expect(this.locator.emergencyContactState).toHaveValue(state);
962+
await this.locator.emergencyContactZip.fill(zip);
963+
return { address, addressLine2, city, state, zip };
964+
}
931965

932966
async checkImagesIsSaved(image: Locator): Promise<void> {
933967
const today = await this.CommonLocatorsHelper.getToday();

apps/intake/tests/utils/locators.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,12 @@ export class Locators {
235235
emergencyContactInformationFirstName: Locator;
236236
emergencyContactInformationLastName: Locator;
237237
emergencyContactInformationPhone: Locator;
238+
emergencyContactSameAddressAsPatient: Locator;
239+
emergencyContactAddress: Locator;
240+
emergencyContactAddressLine2: Locator;
241+
emergencyContactCity: Locator;
242+
emergencyContactState: Locator;
243+
emergencyContactZip: Locator;
238244

239245
constructor(page: Page) {
240246
this.page = page;
@@ -243,9 +249,9 @@ export class Locators {
243249
this.startInPersonVisitButton = page.getByTestId(dataTestIds.startInPersonVisitButton);
244250
this.differentFamilyMember = page.getByTestId(dataTestIds.differentFamilyMember);
245251
this.continueButton = page.getByTestId(dataTestIds.continueButton);
246-
// if (this.continueButton == null) {
247-
// this.continueButton = page.getByText('Continue');
248-
// }
252+
if (this.continueButton == null) {
253+
this.continueButton = page.getByText('Continue');
254+
}
249255
this.flowHeading = page.getByTestId(dataTestIds.flowPageTitle);
250256
this.thankYouHeading = page.getByRole('heading', { name: 'Thank you for choosing Ottehr!' });
251257
this.startInPersonVisitButton = page.getByTestId(dataTestIds.startInPersonVisitButton);
@@ -385,6 +391,12 @@ export class Locators {
385391
this.emergencyContactInformationFirstName = page.locator('[id="emergency-contact-first-name"]');
386392
this.emergencyContactInformationLastName = page.locator('[id="emergency-contact-last-name"]');
387393
this.emergencyContactInformationPhone = page.locator('[id="emergency-contact-number"]');
394+
this.emergencyContactSameAddressAsPatient = page.getByLabel("Same as patient's address");
395+
this.emergencyContactAddress = page.locator('[id="emergency-contact-address"]');
396+
this.emergencyContactAddressLine2 = page.locator('[id="emergency-contact-address-2"]');
397+
this.emergencyContactCity = page.locator('[id="emergency-contact-city"]');
398+
this.emergencyContactState = page.locator('[id="emergency-contact-state"]');
399+
this.emergencyContactZip = page.locator('[id="emergency-contact-zip"]');
388400

389401
// Paperwork calendar locators
390402
this.calendarCurrentDay = page.locator('button[aria-current="date"]');

0 commit comments

Comments
 (0)