Skip to content

Commit

Permalink
feat: geocoding - showing name and relationship on preference screens (
Browse files Browse the repository at this point in the history
…#3703)

* 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

* fix: move address holder name and relationship fields to extraData

* fix: remove redundant backend address holder fields

* fix: use enum for address holder fields
  • Loading branch information
KrissDrawing authored Nov 20, 2023
1 parent 93bea69 commit 9b75efe
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 29 deletions.
1 change: 1 addition & 0 deletions shared-helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export * from "./src/utilities/stringFormatting"
export * from "./src/utilities/token"
export * from "./src/utilities/unitTypes"
export * from "./src/utilities/DateFormat"
export * from "./src/utilities/constants"
export * from "./src/views/multiselectQuestions"
export * from "./src/views/occupancyFormatting"
export * from "./src/views/summaryTables"
Expand Down
3 changes: 3 additions & 0 deletions shared-helpers/src/locales/general.json
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@
"application.preferences.neighborhoodResidence.neighborhoodResidence.label": "Neighborhood Residents Preference",
"application.preferences.neighborhoodResidence.title": "Neighborhood Residents",
"application.preferences.options.address": "Address",
"application.preferences.options.qualifyingAddress": "Qualifying Address",
"application.preferences.options.addressHolderName": "Full Name of Address Holder",
"application.preferences.options.addressHolderRelationship": "Relationship to Address Holder",
"application.preferences.options.organization": "Name of Organization",
"application.preferences.preamble": "If you qualify for this preference, you'll get a higher ranking.",
"application.preferences.rosefieldAUSD.title": "Alameda Unified School District (AUSD) employee",
Expand Down
4 changes: 4 additions & 0 deletions shared-helpers/src/utilities/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum AddressHolder {
Relationship = "addressHolderRelationship",
Name = "addressHolderName",
}
98 changes: 82 additions & 16 deletions shared-helpers/src/views/multiselectQuestions.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import * as React from "react"
import {
InputType,
MultiselectQuestion,
MultiselectOption,
ApplicationMultiselectQuestion,
ApplicationMultiselectQuestionOption,
ApplicationSection,
ListingMultiselectQuestion,
InputType,
Listing,
ListingMultiselectQuestion,
MultiselectOption,
MultiselectQuestion,
} from "@bloom-housing/backend-core/types"
import { UseFormMethods } from "react-hook-form"
import {
t,
Field,
resolveObject,
FormAddress,
ExpandableContent,
Field,
FieldGroup,
FormAddress,
resolveObject,
t,
} from "@bloom-housing/ui-components"
import { stateKeys } from "../utilities/formKeys"
import { AddressHolder } from "../utilities/constants"

export const listingSectionQuestions = (
listing: Listing,
Expand Down Expand Up @@ -235,7 +236,6 @@ export const getCheckboxOption = (
exclusiveKeys
)}
</div>

{option.description && (
<div className="ml-8 -mt-5 mb-5">
<ExpandableContent strings={{ readMore: t("t.readMore"), readLess: t("t.readLess") }}>
Expand All @@ -257,11 +257,41 @@ export const getCheckboxOption = (
</ExpandableContent>
</div>
)}

{watchFields[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")
}
/>
)}
{watchFields[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")
}
/>
)}
{watchFields[optionFieldName] && option.collectAddress && (
<div className="pb-4">
<FormAddress
subtitle={t("application.preferences.options.address")}
subtitle={t("application.preferences.options.qualifyingAddress")}
dataKey={fieldName(question.text, applicationSection, `${option.text}-address`)}
register={register}
errors={errors}
Expand Down Expand Up @@ -317,18 +347,41 @@ export const mapCheckboxesToApi = (
const claimed = !!Object.keys(data).filter((key) => data[key] === true).length

const addressFields = Object.keys(data).filter((option) => Object.keys(data[option]))

const questionOptions: ApplicationMultiselectQuestionOption[] = Object.keys(data)
.filter((option) => !Object.keys(data[option]).length)
.map((key) => {
const extraData = []
const addressData = addressFields.filter((addressField) => addressField === `${key}-address`)
const addressHolderNameData = addressFields.filter(
(addressField) => addressField === `${key}-${AddressHolder.Name}`
)
const addressHolderRelationshipData = addressFields.filter(
(addressField) => addressField === `${key}-${AddressHolder.Relationship}`
)
if (addressData.length) {
extraData.push({ type: InputType.address, key: "address", value: data[addressData[0]] })

if (addressHolderNameData.length) {
extraData.push({
type: InputType.text,
key: AddressHolder.Name,
value: data[addressHolderNameData[0]],
})
}

if (addressHolderRelationshipData.length) {
extraData.push({
type: InputType.text,
key: AddressHolder.Relationship,
value: data[addressHolderRelationshipData[0]],
})
}
}

return {
key,
checked: data[key] === true,
extraData: addressData.length
? [{ type: InputType.address, key, value: data[addressData[0]] }]
: [],
extraData: extraData,
}
})

Expand Down Expand Up @@ -379,11 +432,24 @@ export const mapApiToMultiselectForm = (
if (appQuestion.inputType === "checkbox") {
options = question.options.reduce((acc, curr) => {
const claimed = curr.checked

if (appQuestion.inputType === "checkbox") {
acc[curr.key] = claimed
if (curr.extraData?.length) {
acc[`${curr.key}-address`] = curr.extraData[0].value

const addressHolderName = curr.extraData?.find(
(field) => field.key === AddressHolder.Name
)
if (addressHolderName) {
acc[`${curr.key}-${AddressHolder.Name}`] = addressHolderName.value
}

const addressHolderRelationship = curr.extraData?.find(
(field) => field.key === AddressHolder.Relationship
)
if (addressHolderRelationship) {
acc[`${curr.key}-${AddressHolder.Relationship}`] = addressHolderRelationship.value
}
}
}

Expand Down
26 changes: 14 additions & 12 deletions sites/public/src/components/shared/FormSummaryDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { Fragment, useEffect, useState } from "react"
import { LocalizedLink, MultiLineAddress, t } from "@bloom-housing/ui-components"
import { FieldValue } from "@bloom-housing/ui-seeds"
import { getUniqueUnitTypes } from "@bloom-housing/shared-helpers"
import { getUniqueUnitTypes, AddressHolder } from "@bloom-housing/shared-helpers"
import {
Address,
AllExtraDataTypes,
Expand Down Expand Up @@ -88,21 +88,23 @@ const FormSummaryDetails = ({
}
}

const multiselectQuestionAddress = (extraData?: AllExtraDataTypes[]) => {
const multiselectQuestionHelpText = (extraData?: AllExtraDataTypes[]) => {
if (!extraData) return
return extraData.reduce((acc, item) => {
const helperText = extraData.reduce((acc, item) => {
if (item.type === InputType.address && typeof item.value === "object") {
acc += `
${item.value.street}${!item.value.street2 && ","}
${item.value.street2 ? `${item.value.street2},` : ""}
${item.value.city},
${item.value.state}
${item.value.zipCode}
`
acc += `${item.value.street} ${!item.value.street2 ? "," : ""} ${
item.value.street2 ? `${item.value.street2},` : ""
} ${item.value.city}, ${item.value.state} ${item.value.zipCode}`
}

return acc
}, "")

const name = extraData.find((field) => field.key === AddressHolder.Name)?.value as string
const relationship = extraData.find((field) => field.key === AddressHolder.Relationship)
?.value as string

return `${name ? `${name}\n` : ""}${relationship ? `${relationship}\n` : ""}${helperText}`
}

const multiselectQuestionSection = (
Expand Down Expand Up @@ -134,10 +136,10 @@ const FormSummaryDetails = ({
.map((option: ApplicationMultiselectQuestionOption, index) => (
<FieldValue
label={question.key}
helpText={multiselectQuestionAddress(option?.extraData)}
helpText={multiselectQuestionHelpText(option?.extraData)}
key={index}
testId={"app-summary-preference"}
className={"pb-4"}
className={"pb-6 whitespace-pre-wrap"}
>
{option.key}
</FieldValue>
Expand Down
4 changes: 3 additions & 1 deletion sites/public/src/lib/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,9 @@ export const untranslateMultiselectQuestion = (

if (option.extraData) {
option.extraData.forEach((extra) => {
extra.key = selectedOption.untranslatedText ?? selectedOption.text
if (!extra.key) {
extra.key = selectedOption.untranslatedText ?? selectedOption.text
}
})
}
})
Expand Down

0 comments on commit 9b75efe

Please sign in to comment.