Skip to content

Commit

Permalink
Refactor facilityForm to use react-hook-form
Browse files Browse the repository at this point in the history
  • Loading branch information
emyl3 committed Jun 15, 2023
1 parent e86825c commit e82824d
Show file tree
Hide file tree
Showing 16 changed files with 768 additions and 722 deletions.
20 changes: 10 additions & 10 deletions cypress/e2e/01-organization_sign_up.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,16 @@ describe("Organization sign up",() => {
cy.checkA11y();
});
it("fills out the form for a new facility", () => {
cy.get('input[name="name"]').type(facility.name);
cy.get('input[name="facility-phone"]').first().type("5308675309");
cy.get('input[name="facility-street"]').first().type("123 Beach Way");
cy.get('input[name="facility-zipCode"]').first().type("90210");
cy.get('select[name="facility-state"]').first().select("CA");
cy.get('input[name="cliaNumber"]').type("12D4567890");
cy.get('input[name="firstName"]').type("Phil");
cy.get('input[name="lastName"]').type("McTester");
cy.get('input[name="NPI"]').type("1234567890");
cy.get('input[name="op-phone"]').last().type("5308675309");
cy.get('input[name="facility.name"]').type(facility.name);
cy.get('input[name="facility.phone"]').first().type("5308675309");
cy.get('input[name="facility.street"]').first().type("123 Beach Way");
cy.get('input[name="facility.zipCode"]').first().type("90210");
cy.get('select[name="facility.state"]').first().select("CA");
cy.get('input[name="facility.cliaNumber"]').type("12D4567890");
cy.get('input[name="orderingProvider.firstName"]').type("Phil");
cy.get('input[name="orderingProvider.lastName"]').type("McTester");
cy.get('input[name="orderingProvider.NPI"]').type("1234567890");
cy.get('input[name="orderingProvider.phone"]').last().type("5308675309");
cy.contains("Save changes").last().click();
cy.get(
'.modal__container input[name="addressSelect-facility"][value="userAddress"]+label'
Expand Down
315 changes: 186 additions & 129 deletions frontend/src/app/Settings/Facility/Components/FacilityInformation.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
import React from "react";

import { stateCodes } from "../../../../config/constants";
import {
liveJurisdictions,
stateCodes,
urls,
} from "../../../../config/constants";
import TextInput from "../../../commonComponents/TextInput";
import { FacilityErrors } from "../facilitySchema";
import { ValidateField } from "../FacilityForm";
import { getSubStrAfterChar } from "../../../utils/text";
import Dropdown from "../../../commonComponents/Dropdown";
import {
isValidCLIANumber,
stateRequiresCLIANumberValidation,
} from "../../../utils/clia";
import { getStateNameFromCode } from "../../../utils/state";
import { emailRegex } from "../../../utils/email";
import { phoneNumberIsValid } from "../../../patients/personSchema";
import { FacilityFormData } from "../FacilityForm";
import { zipCodeRegex } from "../../../utils/address";

interface Props {
facility: Facility;
updateFacility: (facility: Facility) => void;
errors: FacilityErrors;
validateField: ValidateField;
setError: any;
newOrg?: boolean;
errors: any;
register: any;
formCurrentValues: FacilityFormData;
getFieldState: any;
}

const FacilityInformation: React.FC<Props> = ({
facility,
updateFacility,
errors,
validateField,
newOrg = false,
errors,
register,
formCurrentValues,
getFieldState,
}) => {
const onChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
) => {
let fieldName = getSubStrAfterChar(e.target.name, "-");
updateFacility({ ...facility, [fieldName]: e.target.value });
const fieldState = getFieldState("facility.state");
const isLiveState = (state: string) => {
return liveJurisdictions.includes(state) && stateCodes.includes(state);
};

return (
Expand All @@ -44,119 +54,166 @@ const FacilityInformation: React.FC<Props> = ({
</p>
</>
)}
<h2 className="font-heading-lg" style={{ margin: 0 }}>
Testing facility information
</h2>
<TextInput
label="Testing facility name"
name="name"
value={facility.name}
required
onChange={onChange}
onBlur={() => {
validateField("name");
}}
validationStatus={errors.name ? "error" : undefined}
errorMessage={errors.name}
/>
<TextInput
label="Phone number"
name="facility-phone"
value={facility.phone}
required
onChange={onChange}
onBlur={() => {
validateField("phone");
}}
validationStatus={errors.phone ? "error" : undefined}
errorMessage={errors.phone}
/>
<TextInput
label="Email"
name="email"
data-testid="facility-email"
value={facility.email || ""}
onChange={onChange}
onBlur={() => {
validateField("email");
}}
validationStatus={errors.email ? "error" : undefined}
errorMessage={errors.email}
/>
<TextInput
label="Street address 1"
name="facility-street"
value={facility.street}
required
onChange={onChange}
onBlur={() => {
validateField("street");
}}
validationStatus={errors.street ? "error" : undefined}
errorMessage={errors.street}
/>
<TextInput
label="Street address 2"
name="facility-streetTwo"
value={facility.streetTwo || ""}
onChange={onChange}
/>
<TextInput
label="City"
name="facility-city"
value={facility.city || ""}
onChange={onChange}
/>
<TextInput
label="ZIP code"
name="facility-zipCode"
value={facility.zipCode}
required
onChange={onChange}
onBlur={() => {
validateField("zipCode");
}}
validationStatus={errors.zipCode ? "error" : undefined}
errorMessage={errors.zipCode}
className="usa-input--medium"
/>
<Dropdown
label="State"
name="facility-state"
selectedValue={facility.state}
options={stateCodes.map((c) => ({ label: c, value: c }))}
defaultSelect
required
onChange={onChange}
onBlur={() => {
validateField("state");
}}
validationStatus={errors.state ? "error" : undefined}
errorMessage={errors.state}
selectClassName="usa-input--medium"
data-testid="facility-state-dropdown"
/>
<TextInput
label="CLIA number"
hintText={
<a
href="https://www.cdc.gov/clia/LabSearch.html#"
target="_blank"
rel="noopener noreferrer"
>
Find my CLIA
</a>
}
name="cliaNumber"
value={facility.cliaNumber}
required
onChange={onChange}
onBlur={() => {
validateField("cliaNumber");
}}
validationStatus={errors.cliaNumber ? "error" : undefined}
errorMessage={errors.cliaNumber}
/>
<fieldset className="usa-fieldset">
<legend>
<h2 className="font-heading-lg" style={{ margin: 0 }}>
Testing facility information
</h2>
</legend>
<TextInput
label="Testing facility name"
name="name"
value={formCurrentValues.facility?.name}
required
registrationProps={register("facility.name", {
required: "Facility name is required",
})}
validationStatus={errors?.facility?.name?.type ? "error" : undefined}
errorMessage={errors?.facility?.name?.message}
/>
<TextInput
label="Phone number"
name="facility-phone"
value={formCurrentValues.facility?.phone}
required
registrationProps={register("facility.phone", {
required: "Facility phone number is required",
validate: {
valid: (facPhone: string) =>
phoneNumberIsValid(facPhone) ||
"Facility phone number is invalid",
},
})}
validationStatus={errors?.facility?.phone?.type ? "error" : undefined}
errorMessage={errors?.facility?.phone?.message}
/>
<TextInput
label="Email"
name="email"
data-testid="facility-email"
value={formCurrentValues.facility?.email ?? undefined}
validationStatus={errors?.facility?.email?.type ? "error" : undefined}
errorMessage={errors?.facility?.email?.message}
registrationProps={register("facility.email", {
required: false,
pattern: {
value: emailRegex,
message: "Email is incorrectly formatted",
},
})}
/>
<TextInput
label="Street address 1"
name="facility-street"
value={formCurrentValues.facility?.street}
required
validationStatus={
errors?.facility?.street?.type ? "error" : undefined
}
errorMessage={errors?.facility?.street?.message}
registrationProps={register("facility.street", {
required: "Facility street is required",
})}
/>
<TextInput
label="Street address 2"
name="facility-streetTwo"
value={formCurrentValues.facility?.streetTwo ?? undefined}
registrationProps={register("facility.streetTwo", {
required: false,
})}
/>
<TextInput
label="City"
name="facility-city"
value={formCurrentValues.facility?.city ?? undefined}
registrationProps={register("facility.city", { required: false })}
/>
<TextInput
label="ZIP code"
name="facility-zipCode"
value={formCurrentValues.facility?.zipCode}
required
validationStatus={
errors?.facility?.zipCode?.type ? "error" : undefined
}
errorMessage={errors?.facility?.zipCode?.message}
registrationProps={register("facility.zipCode", {
required: "Facility ZIP code is required",
pattern: {
value: zipCodeRegex,
message: "Facility ZIP code is invalid",
},
})}
className="usa-input--medium"
/>
<Dropdown
label="State"
name="facility-state"
selectedValue={formCurrentValues.facility?.state}
options={stateCodes.map((c) => ({ label: c, value: c }))}
defaultSelect
required
hintText={
fieldState?.error && (
<span className="display-block margin-top-05 usa-error-message">
See a{" "}
<a href={urls.FACILITY_INFO}>
{" "}
list of states where SimpleReport is supported
</a>
.
</span>
)
}
onChange={() => {}}
validationStatus={errors?.facility?.state?.type ? "error" : undefined}
errorMessage={errors?.facility?.state?.message}
selectClassName="usa-input--medium"
data-testid="facility-state-dropdown"
registrationProps={register("facility.state", {
required: "Facility state is required",
validate: {
liveJurisdiction: (state: string) =>
isLiveState(state) ||
`SimpleReport isn’t currently supported in ${getStateNameFromCode(
state
)}.`,
},
})}
/>
<TextInput
label="CLIA number"
hintText={
<a
href="https://www.cdc.gov/clia/LabSearch.html#"
target="_blank"
rel="noopener noreferrer"
>
Find my CLIA
</a>
}
name="cliaNumber"
value={formCurrentValues.facility?.cliaNumber}
required
validationStatus={
errors?.facility?.cliaNumber?.type ? "error" : undefined
}
errorMessage={errors?.facility?.cliaNumber?.message}
registrationProps={register("facility.cliaNumber", {
required: "Facility CLIA number is required",
validate: {
validCLIA: (clia: string) =>
(stateRequiresCLIANumberValidation(
formCurrentValues.facility.state
)
? isValidCLIANumber(clia, formCurrentValues.facility.state)
: true) ||
"CLIA numbers must be 10 characters (##D#######), or a special temporary number from CA, IL, VT, WA, WY, or the Department of Defense",
},
})}
/>
</fieldset>
</div>
);
};
Expand Down
Loading

0 comments on commit e82824d

Please sign in to comment.