Skip to content

Commit

Permalink
feat: add address holder fields to paper application (#3716)
Browse files Browse the repository at this point in the history
* feat: add collectAddress checkbox with subfields

* test: update preference tests

* fix: add minimum value validation for radius field

* fix: make collect address not required

* fix: expand collect address fields

* fix: change fields order in PreferenceDrawer

* feat: add address holder fields to application

* fix: make added field optional

* fix: display errors properly

* feat: add address holder fields to application summary

* feat: adjust padding for application summary

* feat: add address holder fields to paper application

* fix: use enum for address holder paper application fields

* fix: remove redundant backend fields

* fix: add correct labels, and values for extraData summary

* fix: export geocoding values enum from backend

* fix: display address as last extraData field

* fix: remove placeholders from form

* fix: set default values after listingDto fetched

* style: adjust details multiselect question
  • Loading branch information
KrissDrawing authored Dec 18, 2023
1 parent eb977d5 commit a6acc08
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 54 deletions.
1 change: 1 addition & 0 deletions backend/core/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from "./src/backend-swagger"
export * from "./src/archer-listing"
export * from "./src/Member"
export * from "./src/filter-keys"
export * from "./src/geocoding-keys"
1 change: 1 addition & 0 deletions backend/core/types/src/geocoding-keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "../../src/shared/types/geocoding-values"
6 changes: 1 addition & 5 deletions shared-helpers/src/views/address/FormAddressAlternate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export const FormAddressAlternate = ({
id={`${dataKey}.street`}
name={`${dataKey}.street`}
label={t("application.contact.streetAddress")}
placeholder={t("application.contact.streetAddress")}
validation={{ required: true, maxLength: 64 }}
errorMessage={
resolveObject(`${dataKey}.street`, errors)?.type === "maxLength"
Expand All @@ -43,7 +42,6 @@ export const FormAddressAlternate = ({
id={`${dataKey}.street2`}
name={`${dataKey}.street2`}
label={t("application.contact.apt")}
placeholder={t("application.contact.apt")}
register={register}
error={!!resolveObject(`${dataKey}.street2`, errors)}
validation={{ maxLength: 64 }}
Expand All @@ -54,8 +52,7 @@ export const FormAddressAlternate = ({
<Field
id={`${dataKey}.city`}
name={`${dataKey}.city`}
label={t("application.contact.cityName")}
placeholder={t("application.contact.cityName")}
label={t("application.contact.city")}
register={register}
validation={{ required, maxLength: 64 }}
error={!!resolveObject(`${dataKey}.city`, errors)}
Expand Down Expand Up @@ -87,7 +84,6 @@ export const FormAddressAlternate = ({
id={`${dataKey}.zipCode`}
name={`${dataKey}.zipCode`}
label={t("application.contact.zip")}
placeholder={t("application.contact.zipCode")}
register={register}
validation={{ required, maxLength: 64 }}
error={!!resolveObject(`${dataKey}.zipCode`, errors)}
Expand Down
2 changes: 2 additions & 0 deletions sites/partners/page_content/locale_overrides/general.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"application.details.preferences": "Application Preferences",
"application.details.preferredContact": "Preferred Contact",
"application.details.preferredUnitSizes": "Preferred Unit Sizes",
"application.details.preferences.passedAddressCheck": "Passed Address Check",
"application.details.programs": "Application Programs",
"application.details.residenceAddress": "Residence Address",
"application.details.signatureOnTerms": "Signature on Terms of Agreement",
Expand Down Expand Up @@ -384,6 +385,7 @@
"t.end": "End",
"t.endTime": "End Time",
"t.enterAmount": "Enter amount",
"t.error": "Error",
"t.export": "Export",
"t.exportSuccess": "The file has been exported",
"t.exportToCSV": "Export to CSV",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type DetailsAddressColumnsProps = {
application?: Application
addressObject?: AddressCreate
householdMember?: HouseholdMemberUpdate
small?: boolean
dataTestId?: string
}

Expand All @@ -30,6 +31,7 @@ const DetailsAddressColumns = ({
application,
addressObject,
householdMember,
small,
dataTestId,
}: DetailsAddressColumnsProps) => {
const address = {
Expand Down Expand Up @@ -91,29 +93,38 @@ const DetailsAddressColumns = ({
return (
<>
<FieldValue
className={small && "seeds-grid-span-3"}
label={t("application.contact.streetAddress")}
testId={`${dataTestId}.streetAddress`}
>
{address.street}
</FieldValue>

<FieldValue
className="seeds-grid-span-2"
className={small ? "seeds-grid-span-3" : "seeds-grid-span-2"}
label={t("application.contact.apt")}
testId={`${dataTestId}.street2`}
>
{address.street2}
</FieldValue>

<FieldValue label={t("application.contact.city")} testId={`${dataTestId}.city`}>
<FieldValue
className={small && "seeds-grid-span-2"}
label={t("application.contact.city")}
testId={`${dataTestId}.city`}
>
{address.city}
</FieldValue>

<FieldValue label={t("application.contact.state")} testId={`${dataTestId}.state`}>
{address.state}
</FieldValue>

<FieldValue label={t("application.contact.zip")} testId={`${dataTestId}.zipCode`}>
<FieldValue
className={small && "seeds-grid-span-3"}
label={t("application.contact.zip")}
testId={`${dataTestId}.zipCode`}
>
{address.zipCode}
</FieldValue>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React, { useContext } from "react"
import { t } from "@bloom-housing/ui-components"
import { FieldValue, Grid } from "@bloom-housing/ui-seeds"
import { listingSectionQuestions } from "@bloom-housing/shared-helpers"
import { AddressHolder, listingSectionQuestions } from "@bloom-housing/shared-helpers"
import { ApplicationContext } from "../../ApplicationContext"
import { InputType, AddressCreate, ApplicationSection } from "@bloom-housing/backend-core/types"
import {
InputType,
AddressCreate,
ApplicationSection,
GeocodingValues,
} from "@bloom-housing/backend-core/types"
import { DetailsAddressColumns, AddressColsType } from "../DetailsAddressColumns"
import { useSingleListingData } from "../../../../lib/hooks"
import SectionWithGrid from "../../../shared/SectionWithGrid"
Expand All @@ -14,6 +19,19 @@ type DetailsMultiselectQuestionsProps = {
title: string
}

const formatGeocodingValues = (key: GeocodingValues) => {
switch (key) {
case GeocodingValues.true:
return t("t.yes")
case GeocodingValues.false:
return t("t.no")
case GeocodingValues.unknown:
return t("t.error")
default:
return t("t.error")
}
}

const DetailsMultiselectQuestions = ({
title,
applicationSection,
Expand Down Expand Up @@ -49,45 +67,74 @@ const DetailsMultiselectQuestions = ({
const options = appQuestion?.options?.filter((option) => option.checked)

return options.map((option) => {
const extra = option.extraData?.map((extra) => {
if (extra.type === InputType.text)
return (
<FieldValue key={extra.key} label={t("t.name")}>
<>{extra.value}</>
</FieldValue>
)

if (extra.type === InputType.boolean)
return (
<FieldValue
key={extra.key}
label={t(`application.preferences.options.${extra.key}`, {
county: listingDto?.countyCode,
})}
>
{extra.value ? t("t.yes") : t("t.no")}
</FieldValue>
)

if (extra.type === InputType.address)
return (
<FieldValue
key={extra.key}
label={t(`application.preferences.options.address`, {
county: listingDto?.countyCode,
})}
>
<Grid spacing="lg">
<Grid.Row columns={3}>
<DetailsAddressColumns
type={AddressColsType.preferences}
addressObject={extra.value as AddressCreate}
/>
</Grid.Row>
</Grid>
</FieldValue>
)
})
const extra = option.extraData
?.sort((a, b) => {
if (a.type === InputType.address) return 1
if (b.type === InputType.address) return -1
return 0
})
?.map((extra) => {
if (extra.type === InputType.text) {
let label = ""
let value = extra.value

switch (extra.key) {
case AddressHolder.Name:
label = t(`application.preferences.options.${AddressHolder.Name}`)
break
case AddressHolder.Relationship:
label = t(
`application.preferences.options.${AddressHolder.Relationship}`
)
break
case "geocodingVerified":
label = t("application.details.preferences.passedAddressCheck")
value = formatGeocodingValues(extra.value as GeocodingValues)
break
default:
label = t("t.name")
}

return (
<FieldValue className="my-8" key={extra.key} label={label}>
<>{value}</>
</FieldValue>
)
}

if (extra.type === InputType.boolean)
return (
<FieldValue
key={extra.key}
label={t(`application.preferences.options.${extra.key}`, {
county: listingDto?.countyCode,
})}
>
{extra.value ? t("t.yes") : t("t.no")}
</FieldValue>
)

if (extra.type === InputType.address)
return (
<FieldValue
key={extra.key}
className="field-label-semibold"
label={t(`application.preferences.options.qualifyingAddress`, {
county: listingDto?.countyCode,
})}
>
<Grid spacing="lg">
<Grid.Row columns={3}>
<DetailsAddressColumns
type={AddressColsType.preferences}
addressObject={extra.value as AddressCreate}
small
/>
</Grid.Row>
</Grid>
</FieldValue>
)
})

return (
<div key={option.key}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ const ApplicationForm = ({ listingId, editMode, application }: ApplicationFormPr
defaultValues,
})

const [initialLoad, setInitialLoad] = useState(true)

if (editMode && initialLoad && listingDto) {
formMethods.reset(defaultValues)
setInitialLoad(false)
}

const router = useRouter()

const { applicationsService } = useContext(AuthContext)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React, { useMemo } from "react"
import { Field, t, FormAddress, FieldGroup } from "@bloom-housing/ui-components"
import { Field, t, FieldGroup, resolveObject } from "@bloom-housing/ui-components"
import { FieldValue, Grid } from "@bloom-housing/ui-seeds"
import { useFormContext } from "react-hook-form"
import { stateKeys, getInputType, fieldName } from "@bloom-housing/shared-helpers"
import { stateKeys, getInputType, fieldName, AddressHolder } from "@bloom-housing/shared-helpers"
import {
ApplicationSection,
ListingMultiselectQuestion,
MultiselectOption,
MultiselectQuestion,
} from "@bloom-housing/backend-core/types"
import SectionWithGrid from "../../../shared/SectionWithGrid"
import { FormAddressAlternate } from "@bloom-housing/shared-helpers/src/views/address/FormAddressAlternate"

type FormMultiselectQuestionsProps = {
questions: ListingMultiselectQuestion[]
Expand All @@ -25,7 +26,11 @@ const FormMultiselectQuestions = ({
const formMethods = useFormContext()

// eslint-disable-next-line @typescript-eslint/unbound-method
const { register, watch } = formMethods
const {
register,
watch,
formState: { errors },
} = formMethods

const allOptionFieldNames = useMemo(() => {
const keys = []
Expand Down Expand Up @@ -57,13 +62,47 @@ const FormMultiselectQuestions = ({
label={option.text}
register={register}
/>

{watchQuestions[optionFieldName] && option?.collectName && (
<Field
id={AddressHolder.Name}
name={`${optionFieldName}-${AddressHolder.Name}`}
label={t(`application.preferences.options.${AddressHolder.Name}`)}
register={register}
validation={{ required: true, maxLength: 64 }}
error={!!resolveObject(`${optionFieldName}-${AddressHolder.Name}`, errors)}
errorMessage={
resolveObject(`${optionFieldName}-${AddressHolder.Name}`, errors)?.type ===
"maxLength"
? t("errors.maxLength")
: t("errors.requiredFieldError")
}
/>
)}
{watchQuestions[optionFieldName] && option?.collectRelationship && (
<Field
id={AddressHolder.Relationship}
name={`${optionFieldName}-${AddressHolder.Relationship}`}
label={t(`application.preferences.options.${AddressHolder.Relationship}`)}
register={register}
validation={{ required: true, maxLength: 64 }}
error={!!resolveObject(`${optionFieldName}-${AddressHolder.Relationship}`, errors)}
errorMessage={
resolveObject(`${optionFieldName}-${AddressHolder.Relationship}`, errors)?.type ===
"maxLength"
? t("errors.maxLength")
: t("errors.requiredFieldError")
}
/>
)}
{watchQuestions[optionFieldName] && option.collectAddress && (
<div className="pb-4">
<FormAddress
subtitle={t("application.preferences.options.address")}
<FormAddressAlternate
subtitle={t("application.preferences.options.qualifyingAddress")}
dataKey={fieldName(question.text, applicationSection, `${option.text}-address`)}
register={register}
required={true}
errors={errors}
stateKeys={stateKeys}
data-testid={"app-question-extra-field"}
/>
Expand Down
6 changes: 6 additions & 0 deletions sites/partners/styles/overrides.scss
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,9 @@
--text-caps-spaced-margin-bottom: var(--seeds-s2);
text-transform: none;
}

.field-label-semibold {
> [data-part="label"] {
font-weight: var(--seeds-font-weight-semibold);
}
}

0 comments on commit a6acc08

Please sign in to comment.