CASH-2468 policy info fields saved to store

CASH-2468 policy info fields saved to store
This commit is contained in:
CarlNation 2026-05-11 09:08:47 -04:00
parent cb7705271d
commit df3cdebf2e
4 changed files with 214 additions and 3 deletions

View file

@ -44,6 +44,10 @@ const errorMessages = {
DAMAGE_TYPES_REQUIRED: "How damage occurred is required",
ZIP_CODE_REQUIRED: "Please enter your ZIP code",
ZIP_CODE_FORMAT: "Zip must be 5 digits",
DATE_OF_BIRTH_REQUIRED: "Please enter your date of birth",
LOSS_TIME_REQUIRED: "Please enter your loss time",
LOSS_LOCATION_REQUIRED: "Please select your loss location",
SUBROGATION_REQUIRED: "Please make a selection",
};
export { errorMessages };

View file

@ -26,7 +26,8 @@
:min-date="minDate"
:max-date="maxDate"
:auto-apply="autoApply"
:text-input="textInput"
:text-input="resolvedTextInput"
:hide-input-icon="textInputOnly"
:prevent-min-max-navigation="preventMinMaxNavigation"
:teleport="true"
:aria-labels="{ input: questionText }"
@ -107,6 +108,12 @@ export default {
type: Boolean,
default: false,
},
// Force manual entry: text input enabled, calendar popup never opens
// and the calendar icon is hidden.
textInputOnly: {
type: Boolean,
default: false,
},
preventMinMaxNavigation: {
type: Boolean,
default: false,
@ -155,7 +162,7 @@ export default {
questionText() {
if (!this.cmsWidgetName) return "";
const text = this.getCmsContent
? this.getCmsContent(this.cmsWidgetName, "BodyText")
? this.getCmsContent(this.cmsWidgetName, "QuestionText")
: "";
return this.addOptionalText ? `${text} (optional)` : text;
},
@ -193,6 +200,15 @@ export default {
clearable: this.clearable,
};
},
// Forwarded to VueDatePicker's `text-input` prop. When `textInputOnly`
// is set, force text input on AND tell the picker never to open its
// menu (so focus/click on the input is a no-op visually).
resolvedTextInput() {
if (this.textInputOnly) {
return { enabled: true, openMenu: false };
}
return this.textInput;
},
},
methods: {
onDateChange(newValue) {

View file

@ -28,6 +28,40 @@
inputId="policyNumber"
validationRules="policy-number-required" />
<datePickerPopup
v-if="displayDateOfBirth"
isRequired
class="mb-4"
cmsWidgetName="DateOfBirthWidget"
v-model="dateOfBirth"
customInputId="dateOfBirth"
placeholderText="MM/DD/YYYY"
validationRules="date-of-birth-required"
format="MM/dd/yyyy"
modelType="MM/dd/yyyy"
:enableTimePicker="false"
:textInputOnly="true"
:maxDate="today"
:preventMinMaxNavigation="true" />
<textboxQuestion
v-if="displayLastName"
isRequired
class="mb-4"
cmsWidgetName="LastNameWidget"
v-model="lastName"
inputId="lastName"
validationRules="last-name-required" />
<textboxQuestion
v-if="displayStreetAddress"
isRequired
class="mb-4"
cmsWidgetName="StreetAddressWidget"
v-model="streetAddress"
inputId="streetAddress"
validationRules="street-address-required" />
<textboxQuestion
isRequired
class="mb-4"
@ -72,6 +106,18 @@
:maxDate="today"
:preventMinMaxNavigation="true" />
<dropdownQuestion
isRequired
:questionText="timeOfLossQuestionText"
class="mb-4"
v-model="lossTime"
cmsWidgetName="TimeOfLossWidget"
customDropdownId="lossTime"
:options="lossTimeOptions"
:valueAsKey="true"
validationRules="loss-time-required"
:labelBold="true" />
<dropdownQuestion
isRequired
:questionText="damageTypesQuestionText"
@ -84,7 +130,19 @@
validationRules="damage-types-required"
:labelBold="true" />
<buttonQuestion
v-if="displaySubrogation"
:questionText="subrogationQuestionText"
:answers="subrogationAnswers"
class="mb-4"
groupName="SubrogationQuestion"
buttonTypeString="listButton"
isRequired
validationRules="subrogation-required"
v-model="subrogationSelectedValue" />
<dropdownQuestion
v-if="displayLossState"
class="mb-4"
customDropdownId="policyState"
cmsWidgetName="StateQuestionWidget"
@ -96,7 +154,20 @@
placeHolderText="Select State"
:labelBold="true" />
<dropdownQuestion
v-if="displayLossLocation"
:questionText="lossLocationQuestionText"
class="mb-4"
v-model="lossLocation"
cmsWidgetName="LossLocationQuestionWidget"
customDropdownId="lossLocation"
:options="lossLocationOptions"
:valueAsKey="true"
validationRules="loss-location-required"
:labelBold="true" />
<textboxQuestion
v-if="displayLossCity"
isRequired
class="mb-4"
cmsWidgetName="CityWidget"
@ -133,6 +204,7 @@ import textboxQuestion from "@/digital-components/textbox-question/textbox-quest
import datePickerPopup from "@/digital-components/date-picker-popup/date-picker-popup";
import dropdownQuestion from "@/digital-components/dropdown-question/dropdown-question";
import morePolicyQuestions from "@/layouts/policy-info/more-policy-questions/more-policy-questions";
import buttonQuestion from "@/digital-components/button-question/button-question";
import { stateOptions } from "@/constants/state-options";
import { Form, defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
@ -142,6 +214,7 @@ import { regex } from "@/helpers/validation-rules";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import store from "@/store";
import { debugLog } from "@/helpers/debug-log-helper";
defineRule("policy-number-required", required(errorMessages.POLICY_NUMBER_REQUIRED));
defineRule("zip-code-required", required(errorMessages.ZIP_REQUIRED));
@ -151,6 +224,12 @@ defineRule("date-of-loss-required", required(errorMessages.DATE_OF_LOSS_REQUIRED
defineRule("damage-types-required", required(errorMessages.DAMAGE_TYPES_REQUIRED));
defineRule("state-required", required(errorMessages.STATE_REQUIRED));
defineRule("city-required", required(errorMessages.CITY_REQUIRED));
defineRule("date-of-birth-required", required(errorMessages.DATE_OF_BIRTH_REQUIRED));
defineRule("last-name-required", required(errorMessages.LAST_NAME_REQUIRED));
defineRule("street-address-required", required(errorMessages.STREET_ADDRESS_REQUIRED));
defineRule("loss-time-required", required(errorMessages.LOSS_TIME_REQUIRED));
defineRule("loss-location-required", required(errorMessages.LOSS_LOCATION_REQUIRED));
defineRule("subrogation-required", required(errorMessages.SUBROGATION_REQUIRED));
export default {
name: "policy-info",
@ -163,10 +242,16 @@ export default {
phoneNumber: this.getPhoneNumberFromStore(),
phoneExtension: this.getPhoneExtensionFromStore(),
dateOfLoss: this.getDateOfLossFromStore(),
lastName: this.getLastNameFromStore(),
streetAddress: this.getStreetAddressFromStore(),
damageCause: this.getDamageCauseFromStore(),
policyState: this.getPolicyStateFromStore(),
city: this.getCityFromStore(),
morePolicyQuestions: [],
dateOfBirth: this.getDateOfBirthFromStore(),
lossTime: this.getLossTimeFromStore(),
morePolicyQuestions: this.getMorePolicyQuestionsFromStore(),
subrogationSelectedValue: this.getSubrogationSelectedValueFromStore(),
lossLocation: this.getLossLocationFromStore(),
};
},
components: {
@ -179,6 +264,7 @@ export default {
datePickerPopup,
dropdownQuestion,
morePolicyQuestions,
buttonQuestion,
},
computed: {
stateOptions() {
@ -206,6 +292,72 @@ export default {
return options;
},
lossTimeOptions() {
const options = {};
const answers = this.getCmsContent("TimeOfLossWidget", "Answers");
for (const answer of answers) {
options[answer.Name] = answer.Text;
}
return options;
},
timeOfLossQuestionText() {
return this.getCmsContent("TimeOfLossWidget", "QuestionText");
},
lossLocationOptions() {
const options = {};
const answers = this.getCmsContent("LossLocationQuestionWidget", "Answers");
for (const answer of answers) {
options[answer.Name] = answer.Text;
}
return options;
},
parsedClientConfig() {
const raw = this.clientConfig?.ConfigWidget?.Text;
if (!raw) return {};
try {
return JSON.parse(raw);
} catch (err) {
console.warn("Failed to parse clientConfig.ConfigWidget.Text", err);
return {};
}
},
displayLossState() {
return this.parsedClientConfig.displayLossState ?? false;
},
displayLossCity() {
return this.parsedClientConfig.displayLossCity ?? false;
},
displayLossLocation() {
return this.parsedClientConfig.displayLossLocation ?? false;
},
displaySubrogation() {
return this.parsedClientConfig.displaySubrogation ?? false;
},
displayStreetAddress() {
return this.parsedClientConfig.displayStreetAddress ?? false;
},
displayDateOfBirth() {
return this.parsedClientConfig.displayDateOfBirth ?? false;
},
displayLastName() {
return this.parsedClientConfig.displayLastName ?? false;
},
displayLossTime() {
return this.parsedClientConfig.displayLossTime ?? false;
},
subrogationQuestionText() {
return this.getCmsContent("SubrogationQuestionWidget", "QuestionText");
},
subrogationAnswers() {
return this.getCmsContent("SubrogationQuestionWidget", "Answers");
},
lossLocationQuestionText() {
return this.getCmsContent("LossLocationQuestionWidget", "QuestionText");
},
},
// Ensure CMS content is fetched during route navigation without depending on `to`/`from`
async beforeRouteEnter(to, from, next) {
@ -228,6 +380,7 @@ export default {
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.clientConfig = resultMap.clientConfig;
debugLog(`clientConfig::${clientConfigPageName}`, JSON.stringify(vm.clientConfig));
});
},
@ -256,6 +409,27 @@ export default {
getCityFromStore() {
return store.getters.order.policy.city;
},
getDateOfBirthFromStore() {
return store.getters.order.policy.dateOfBirth;
},
getLastNameFromStore() {
return store.getters.order.policy.lastName;
},
getStreetAddressFromStore() {
return store.getters.order.policy.streetAddress;
},
getLossTimeFromStore() {
return store.getters.order.policy.lossTime;
},
getSubrogationSelectedValueFromStore() {
return store.getters.order.policy.subrogation;
},
getMorePolicyQuestionsFromStore() {
return store.getters.order.policy.morePolicyQuestions ?? [];
},
getLossLocationFromStore() {
return store.getters.order.policy.lossLocation;
},
backButtonAction() {
this.$router.navigateWithoutSaving(
this.navigationScenarios.CLICKED_BACK,
@ -273,6 +447,12 @@ export default {
state: this.policyState,
city: this.city,
morePolicyQuestions: this.morePolicyQuestions,
lossLocation: this.lossLocation,
lossTime: this.lossTime,
lastName: this.lastName,
dateOfBirth: this.dateOfBirth,
subrogation: this.subrogationSelectedValue,
streetAddress: this.streetAddress,
},
false
);

View file

@ -182,6 +182,11 @@ const getDefaultState = () => {
city: null,
state: null,
zipCode: null,
dateOfBirth: null,
lossTime: null,
lossLocation: null,
lastName: null,
subrogation: null,
},
schedule: {
date: null,
@ -559,6 +564,12 @@ export const mutations = {
state.order.policy.phoneNumber = insuranceDetails.phoneNumber;
state.order.policy.phoneExtension = insuranceDetails.phoneExtension;
state.order.policy.morePolicyQuestions = insuranceDetails.morePolicyQuestions;
state.order.policy.dateOfBirth = insuranceDetails.dateOfBirth;
state.order.policy.lossTime = insuranceDetails.lossTime;
state.order.policy.lastName = insuranceDetails.lastName;
state.order.policy.lossLocation = insuranceDetails.lossLocation;
state.order.policy.subrogation = insuranceDetails.subrogation;
state.order.policy.streetAddress = insuranceDetails.streetAddress;
}
},
updateDamageDetails(state, damageDetails) {