INSR-7772: tpa-submit parity updates

- Rearrange/style tpa-submit page
- Update supporting components to better match heritage
    - DeductibleBox
    - ReviewBlock
    - Alert
- Update store logic to actually handle extension
- Add/update recal modal and contact details modal
- Update titleCase to treat dashes like spaces
This commit is contained in:
Alex Humphries 2026-01-21 15:09:10 -05:00
parent 23223e759d
commit b0b31df8b0
9 changed files with 299 additions and 226 deletions

View file

@ -71,6 +71,9 @@ export const pageProgressMapper = {
'tpa-search': { 'tpa-search': {
percent: 85 percent: 85
}, },
'tpa-submit': {
percent: 95
},
'tpa-confirmation': { 'tpa-confirmation': {
percent: 100 percent: 100
}, },

View file

@ -34,11 +34,8 @@ export function createOrderedListFromStringOfParagraphs(stringOfParagraphs) {
* @returns {string} * @returns {string}
*/ */
export function toTitleCase(text) { export function toTitleCase(text) {
const temp = text?.toLowerCase()?.split(' ') ?? []; let temp = text.toLowerCase();
for (let i = 0; i < temp.length; i++) { return temp.replace(/(^|\s|-)\S/g, (letter) => letter.toUpperCase());
temp[i] = temp[i].charAt(0).toUpperCase() + temp[i].slice(1);
}
return temp.join(' ');
} }
/** /**

View file

@ -1,6 +1,7 @@
<template> <template>
<modal <modal
:ref="modalName" :ref="modalName"
:modalPosition="modalPositions.center"
:headerText="headerText" :headerText="headerText"
:footerButtonText="footerButtonText" :footerButtonText="footerButtonText"
:onModalClosedCallback="resetFormValues" :onModalClosedCallback="resetFormValues"
@ -8,25 +9,27 @@
@isModalOpened="setModalStatus" @isModalOpened="setModalStatus"
@footerButtonEvent="clickFooterButtonEvent"> @footerButtonEvent="clickFooterButtonEvent">
<template v-if="isModalOpened"> <template v-if="isModalOpened">
<textboxQuestion <div class="row">
ref="firstNameQuestion" <textboxQuestion
v-model="firstName" class="col"
inputId="firstName" ref="firstNameQuestion"
:cmsWidgetName="widget.firstNameQuestion" v-model="firstName"
isRequired inputId="firstName"
:validationRules="rules.firstName" /> :cmsWidgetName="widget.firstNameQuestion"
<textboxQuestion isRequired
ref="lastNameQuestion" :validationRules="rules.firstName" />
v-model="lastName" <textboxQuestion
class="mt-4" class="col"
inputId="lastName" ref="lastNameQuestion"
:cmsWidgetName="widget.lastNameQuestion" v-model="lastName"
isRequired inputId="lastName"
:validationRules="rules.lastName" /> :cmsWidgetName="widget.lastNameQuestion"
isRequired
:validationRules="rules.lastName" />
</div>
<textboxQuestion <textboxQuestion
ref="emailQuestion" ref="emailQuestion"
v-model="emailAddress" v-model="emailAddress"
class="mt-4"
inputId="emailAddress" inputId="emailAddress"
:cmsWidgetName="widget.emailQuestion" :cmsWidgetName="widget.emailQuestion"
isRequired isRequired
@ -34,13 +37,19 @@
<textboxQuestion <textboxQuestion
ref="phoneNumberQuestion" ref="phoneNumberQuestion"
v-model="phoneNumber" v-model="phoneNumber"
class="mt-4"
inputId="phoneNumber" inputId="phoneNumber"
:cmsWidgetName="widget.phoneNumberQuestion" :cmsWidgetName="widget.phoneNumberQuestion"
isRequired isRequired
:mask="phoneMask" :mask="phoneMask"
disableAutoFill disableAutoFill
:validationRules="rules.phoneNumber" /> :validationRules="rules.phoneNumber" />
<textboxQuestion
ref="extensionQuestion"
v-model="extension"
inputId="extension"
:cmsWidgetName="widget.extensionQuestion"
disableAutoFill
:validationRules="rules.extension" />
</template> </template>
</modal> </modal>
</template> </template>
@ -51,10 +60,11 @@ import modal from '@/digital-components/modal/modal.vue';
import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue'; import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
// Supporting Files // Supporting Files
import { useMainStore } from '@/store/index.js'; import { useMainStore } from '@/store';
import globalRules from '@/constants/global-rules.js'; import globalRules from '@/constants/global-rules.js';
import MaskaFormattedMasks from '@/constants/maska-masks'; import MaskaFormattedMasks from '@/constants/maska-masks';
import widgetFields from '@/constants/cms-widget-fields.js'; import widgetFields from '@/constants/cms-widget-fields.js';
import { modalPositions } from '@/constants/component-variants';
export default { export default {
name: 'contact-details-drawer', name: 'contact-details-drawer',
@ -67,27 +77,39 @@ export default {
const { firstName, const { firstName,
lastName, lastName,
emailAddress, emailAddress,
servicePhone } = useMainStore().contactInfo; servicePhone,
extension } = useMainStore().contactInfo;
console.log('Initial contact info loaded:', {
firstName,
lastName,
emailAddress,
servicePhone,
extension
});
return { return {
isModalOpened: false, isModalOpened: false,
firstName, firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber: servicePhone, phoneNumber: servicePhone,
extension: extension,
widget: { widget: {
title: 'ContactDetailsDrawerHeaderWidget', title: 'ContactDetailsDrawerHeaderWidget',
firstNameQuestion: 'FirstNameQuestionWidget', firstNameQuestion: 'FirstNameQuestionWidget',
lastNameQuestion: 'LastNameQuestionWidget', lastNameQuestion: 'LastNameQuestionWidget',
emailQuestion: 'EmailQuestionWidget', emailQuestion: 'EmailQuestionWidget',
phoneNumberQuestion: 'PhoneNumberQuestionWidget', phoneNumberQuestion: 'PhoneNumberQuestionWidget',
extensionQuestion: 'ExtensionQuestionWidget',
drawerFooter: 'ContactDetailsDrawerFooterWidget' drawerFooter: 'ContactDetailsDrawerFooterWidget'
}, },
rules: { rules: {
firstName: globalRules.FIRST_NAME_REQUIRED, firstName: globalRules.FIRST_NAME_REQUIRED,
lastName: globalRules.LAST_NAME_REQUIRED, lastName: globalRules.LAST_NAME_REQUIRED,
emailAddress: `${globalRules.EMAIL_ADDRESS_REQUIRED}|${globalRules.EMAIL_ADDRESS_FORMAT}`, emailAddress: `${globalRules.EMAIL_ADDRESS_REQUIRED}|${globalRules.EMAIL_ADDRESS_FORMAT}`,
phoneNumber: `${globalRules.PHONE_NUMBER_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}` phoneNumber: `${globalRules.PHONE_NUMBER_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}`,
} extension: `${globalRules.EXTENSION_FORMAT}`
},
modalPositions
}; };
}, },
computed: { computed: {
@ -121,10 +143,11 @@ export default {
lastName: this.lastName, lastName: this.lastName,
emailAddress: this.emailAddress emailAddress: this.emailAddress
}; };
useMainStore().updateContactInfo(contactInfo); this.mainStore.updateContactInfo(contactInfo);
useMainStore().updatePhoneNumbers({ this.mainStore.updatePhoneNumbers({
home: this.phoneNumber, home: this.phoneNumber,
service: this.phoneNumber service: this.phoneNumber,
extension: this.extension
}); });
this.$emit('update-contact-details'); this.$emit('update-contact-details');
}, },
@ -132,11 +155,20 @@ export default {
const { firstName, const { firstName,
lastName, lastName,
emailAddress, emailAddress,
servicePhone } = useMainStore().contactInfo; servicePhone,
extension } = this.mainStore.contactInfo;
console.log('Resetting form values to:', {
firstName,
lastName,
emailAddress,
servicePhone,
extension
});
this.firstName = firstName; this.firstName = firstName;
this.lastName = lastName; this.lastName = lastName;
this.emailAddress = emailAddress; this.emailAddress = emailAddress;
this.phoneNumber = servicePhone; this.phoneNumber = servicePhone;
this.extension = extension;
}, },
openModal() { openModal() {
this.modal.openModal(); this.modal.openModal();
@ -155,5 +187,14 @@ export default {
font-size: $h5-font-size; font-size: $h5-font-size;
font-weight: $font-weight-normal !important; font-weight: $font-weight-normal !important;
} }
.textbox-question {
margin-bottom: 1.25rem;
:deep(label:has(b)) {
font-weight: $font-weight-normal;
b {
font-weight: 600;
}
}
}
} }
</style> </style>

View file

@ -1,17 +1,9 @@
<template> <template>
<div <div
id="deductibleBox" id="deductibleBox"
class="deductible-box d-flex justify-content-between align-items-center py-2"> class="deductible-box">
<p <span class="deductible-label">Deductible:</span>
id="deductibleLabel" <span class="deductible-value">{{ value }}</span>
class="deductible-box__text">
Deductible
</p>
<p
id="deductibleValue"
class="deductible-box__text">
{{ value }}
</p>
</div> </div>
</template> </template>
@ -28,12 +20,17 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.deductible-box { .deductible-box {
background-color: $green; display: flex;
align-items: center;
gap: .25rem;
} }
.deductible-label {
.deductible-box__text { color: $black;
color: white; font-weight: 600;
}
.deductible-value {
color: $green;
font-weight: 500; font-weight: 500;
margin: 0; font-size: 1.625rem;
} }
</style> </style>

View file

@ -1,29 +1,28 @@
<template> <template>
<div class="review-block"> <div class="review-block">
<div class="d-flex justify-content-between"> <p class="review-block__header">
<p class="review-block__header small-strong pb-1"> {{ customHeaderText }}
{{ customHeaderText }}
</p>
<textLink
linkType="textSmall"
:text="editLinkText"
useLoadingModal
href="javascript:void(0)"
class="link"
@clickEvent="editClicked">
<template
v-if="editScreenReaderTextCmsWidgetName"
#after-text>
<span class="sr-only"> {{ screenReaderOnlyText }} </span>
</template>
</textLink>
</div>
<p
v-for="line in lines"
:key="line"
class="small review-block__body--line"
v-html="line">
</p> </p>
<div class="review-body">
<p
v-for="line in lines"
:key="line"
v-html="line">
</p>
</div>
<textLink
linkType="text"
:text="editLinkText"
useLoadingModal
href="javascript:void(0)"
class="link"
@clickEvent="editClicked">
<template
v-if="editScreenReaderTextCmsWidgetName"
#after-text>
<span class="sr-only"> {{ screenReaderOnlyText }} </span>
</template>
</textLink>
</div> </div>
</template> </template>
@ -36,14 +35,13 @@ export default {
props: { props: {
customHeaderText: String, customHeaderText: String,
editScreenReaderTextCmsWidgetName: String, editScreenReaderTextCmsWidgetName: String,
lines: Array lines: Array,
editLinkText: {
type: String,
default: 'Edit'
},
}, },
emits: ['click-edit'], emits: ['click-edit'],
data() {
return {
editLinkText: 'Edit'
};
},
methods: { methods: {
editClicked() { editClicked() {
this.$emit('click-edit'); this.$emit('click-edit');
@ -59,12 +57,16 @@ export default {
} }
.review-block__header { .review-block__header {
color: $black; color: $black;
font-weight: $font-weight-bold;
margin-bottom: .625rem;
} }
.review-block__body--line {
color: $gray-600; .review-body {
margin-bottom: .625rem
} }
.link { .link {
text-underline-offset: 1px; font-weight: $font-weight-normal
} }
} }
</style> </style>

View file

@ -13,53 +13,52 @@
</div> </div>
<div class="iss-heritage-container-width"> <div class="iss-heritage-container-width">
<div class="tpa-submit-container iss-heritage-content-container-width"> <div class="tpa-submit-container iss-heritage-content-container-width">
<!-- TODO fix styling --> <alert
ref="alertIncomplete"
alertClass="alert-warning"
:cmsWidgetName="widget.alertIncomplete"
/>
<textBlock <textBlock
ref="subHeaderTitle" ref="subHeaderTitle"
:customText="subHeaderTitle" :customText="subHeaderTitle"
justifyText="center" class="tpa-submit-title"/>
:marginTopSizeOverride="4"
class="text-color--black fs-5 tpa-submit__title--line-height" />
<textBlock <textBlock
id="tpaSubmitSubHeaderBodyOne" id="tpaSubmitSubHeaderBodyOne"
ref="tpaSubmitSubHeaderBodyOne" ref="tpaSubmitSubHeaderBodyOne"
:customText="subHeaderBodyOne" :customText="subHeaderBodyOne" />
class="small text-color--darker-gray" /> <alert
<textBlock v-if="recalibrationRequired"
id="tpaSubmitSubHeaderBodyTwo" ref="alertRecalWarning"
ref="tpaSubmitSubHeaderBodyTwo" alertClass="alert-warning recal-alert"
:customText="subHeaderBodyTwo" :isCollapsible="true"
class="mb-4 small text-color--darker-gray" /> :cmsWidgetName="widget.alertRecalWarning"
<buttonMain @textLinkClicked="openRecalModal" />
ref="buttonMainOne" <modal
variant="success" ref="recalModal"
:buttonText="forwardButtonText" class="recal-modal"
class="w-100 mb-5" :modalPosition="modalPositions.center"
@clickEvent="forwardButtonAction" /> :headerText="recalModalContent.headerText"
<hr class="mb-0" /> :footerButtonText="recalModalContent.footerButtonText"
@footerButtonEvent="closeRecalModal">
<div class="recal-modal-subheader">{{ recalModalContent.subHeaderText }}</div>
<img class="recal-modal-image" :src="recalModalContent.image" />
<div class="recal-modal-body" v-html="recalModalContent.bodyText"></div>
</modal>
<hr />
<div id="serviceSummarySection"> <div id="serviceSummarySection">
<textBlock <div
id="tpaSubmitServiceSummaryTitle" v-for="(section, index) in sections"
ref="tpaSubmitServiceSummaryTitle" :key="section.title">
:customText="serviceSummaryText" <hr v-if="index !== 0" />
:marginTopSizeOverride="4" <reviewBlock
class="fw-bold fs-1 lh-lg text-color--black" /> :id="'review-block-' + index"
<div class="px-4 my-3"> :customHeaderText="section.title"
<div :lines="section.lines"
v-for="(section, index) in sections" :editLinkText="section.editLinkText"
:key="section.title"> @clickEdit="() => section.onClickEdit()" />
<hr
v-if="index !== 0"
class="my-3" />
<reviewBlock
:id="'review-block-' + index"
:customHeaderText="section.title"
:lines="section.lines"
@clickEdit="() => section.onClickEdit()" />
</div>
</div> </div>
</div> </div>
<hr class="mb-0" /> <hr />
<div <div
id="submitOrderDetailsSection" id="submitOrderDetailsSection"
ref="submitOrderDetailsSection"> ref="submitOrderDetailsSection">
@ -67,17 +66,10 @@
id="tpaSubmitOrderDetailsTitle" id="tpaSubmitOrderDetailsTitle"
ref="tpaSubmitOrderDetailsTitle" ref="tpaSubmitOrderDetailsTitle"
:customText="orderDetailsTitle" :customText="orderDetailsTitle"
:marginTopSizeOverride="4" :marginTopSizeOverride="0"
class="fw-bold text-color--black" /> class="fw-bold order-details-title" />
<textBlock
id="tpaSubmitOrderDetailsBody"
ref="tpaSubmitOrderDetailsBody"
:customText="orderDetailsBody"
:marginTopSizeOverride="4"
class="mb-4 px-4 small text-color--darker-gray" />
<deductibleBox <deductibleBox
ref="deductibleBox" ref="deductibleBox"
class="px-3"
:value="deductibleBoxValue" /> :value="deductibleBoxValue" />
</div> </div>
<siteFooter <siteFooter
@ -104,6 +96,8 @@ import reviewBlock from '@/layouts/tpa-submit/review-block/review-block.vue';
import deductibleBox from '@/layouts/tpa-submit/deductible-box/deductible-box.vue'; import deductibleBox from '@/layouts/tpa-submit/deductible-box/deductible-box.vue';
import contactDetailsDrawer from '@/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.vue'; import contactDetailsDrawer from '@/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import alert from '@/ux-components/alert/alert.vue';
import modal from '@/digital-components/modal/modal.vue';
// Supporting files // Supporting files
import { import {
@ -114,21 +108,16 @@ import {
import { Form } from 'vee-validate'; import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js';
import widgetFields from '@/constants/cms-widget-fields.js'; import widgetFields from '@/constants/cms-widget-fields.js';
import { useMainStore } from '@/store';
import { import {
toTitleCase, toTitleCase,
toDisplayPhoneNumber, toDisplayPhoneNumber,
formatAddress, formatAddress,
formatAmountInDollars formatAmountInDollars
} from '@/helpers/text-helper.js'; } from '@/helpers/text-helper.js';
import {
getDamageDisplayContent,
getLocationAnswer
} from '@/helpers/damage-review-content-generator.js';
import damageLocationsSelected from '@/constants/damage-locations-selected.js';
import { submitWorkOrder } from '@/helpers/order-helper.js'; import { submitWorkOrder } from '@/helpers/order-helper.js';
import bailoutMessage from '@/constants/bailoutMessage'; import bailoutMessage from '@/constants/bailoutMessage';
import submitType from '@/constants/submit-type'; import submitType from '@/constants/submit-type';
import { modalPositions } from '@/constants/component-variants';
const VERIFYING_COVERAGE = 'Verifying coverage'; const VERIFYING_COVERAGE = 'Verifying coverage';
@ -143,7 +132,9 @@ export default {
siteFooter, siteFooter,
contactDetailsDrawer, contactDetailsDrawer,
// eslint-disable-next-line vue/no-reserved-component-names // eslint-disable-next-line vue/no-reserved-component-names
Form Form,
alert,
modal
}, },
mixins: [BaseFormMixin], mixins: [BaseFormMixin],
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
@ -154,27 +145,19 @@ export default {
}); });
}, },
data() { data() {
const { companyName } = useMainStore().order.serviceLocation.provider;
return { return {
sections: [], sections: [],
widget: { widget: {
siteHeader: 'SiteHeaderWidget', siteHeader: 'SiteHeaderWidget',
siteSubHeader: 'SiteSubHeaderWidget', siteSubHeader: 'SiteSubHeaderWidget',
serviceSummary: 'ServiceSummaryContent',
subheader: {
vehicle: 'VehicleSubTitle',
damage: 'DamageSubTitle',
shop: 'PreferredShopSubTitle',
contactInfo: 'ContactDetailsSubTitle'
},
damageLocations: 'DamageLocationsWidget',
orderDetails: 'OrderDetailsContent', orderDetails: 'OrderDetailsContent',
footer: 'SiteFooterWidget' footer: 'SiteFooterWidget',
alertIncomplete: 'AlertIncompleteWidget',
alertRecalWarning: 'AlertRecalWarningWidget',
editShopLinkText: 'EditShopLinkTextWidget',
contactDetails: 'ContactDetailsSectionWidget'
}, },
companyName, modalPositions
customValueMap: {
glassShop: companyName
}
}; };
}, },
computed: { computed: {
@ -227,53 +210,21 @@ export default {
); );
}, },
isVerified() { isVerified() {
return useMainStore().isVerified; return this.mainStore.isVerified;
}, },
currentDeductible() { currentDeductible() {
return useMainStore().order.currentDeductible; return this.mainStore.order.currentDeductible;
}, },
deductibleBoxValue() { deductibleBoxValue() {
return this.isVerified return this.isVerified
? formatAmountInDollars(this.currentDeductible) ? formatAmountInDollars(this.currentDeductible)
: VERIFYING_COVERAGE; : VERIFYING_COVERAGE;
}, },
getVehicleLines() { getPreferredShopTitle() {
const { year, make, model } = useMainStore().order.vehicle; return toTitleCase(this.mainStore.order.serviceLocation.provider.companyName ?? '');
const line = [year, make, model]
.filter((v) => v != null && v !== '')
.join(' ');
return [line];
},
locationAnswers() {
return this.getInputQuestionWidgetAnswersNullSafe(this.widget.damageLocations);
},
driverSideDamageAnswers() {
const answerContent = getLocationAnswer(
damageLocationsSelected.DRIVER,
this.locationAnswers
);
return this.getInputQuestionWidgetAnswersNullSafe(answerContent?.SubWidgetName);
},
passengerSideDamageAnswers() {
const answerContent = getLocationAnswer(
damageLocationsSelected.PASSENGER,
this.locationAnswers
);
return this.getInputQuestionWidgetAnswersNullSafe(answerContent?.SubWidgetName);
},
getDamageLines() {
const { glassToReplace, isRepair } = useMainStore().order.damage;
return getDamageDisplayContent(
this.locationAnswers,
this.driverSideDamageAnswers,
this.passengerSideDamageAnswers,
glassToReplace,
isRepair
);
}, },
getPreferredShopLines() { getPreferredShopLines() {
const { phoneNumber, address } = const { phoneNumber, address } = this.mainStore.order.serviceLocation.provider;
useMainStore().order.serviceLocation.provider;
const { streetAddress, city, state, zipCode } = address; const { streetAddress, city, state, zipCode } = address;
const displayAddress = formatAddress( const displayAddress = formatAddress(
streetAddress, streetAddress,
@ -284,58 +235,82 @@ export default {
); );
const displayPhoneNumber = toDisplayPhoneNumber(phoneNumber); const displayPhoneNumber = toDisplayPhoneNumber(phoneNumber);
return [ return [
toTitleCase(this.companyName ?? ''),
displayAddress, displayAddress,
displayPhoneNumber displayPhoneNumber
]; ];
}, },
getEditShopLinkText() {
return this.getCmsContent(
this.widget.editShopLinkText,
widgetFields.TEXT_BLOCK_WIDGET.TEXT
);
},
getContactInfoTitle() {
const cmsContent = this.getCmsContent(
this.widget.contactDetails,
widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT
);
return getStringWithCustomValues(cmsContent, this.customValueMap);
},
getContactInfoLines() { getContactInfoLines() {
const { firstName, lastName, emailAddress, servicePhone } = const cmsContent = this.getCmsContent(
useMainStore().contactInfo; this.widget.contactDetails,
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
);
return [ return [
`${firstName} ${lastName}`, getStringWithCustomValues(cmsContent, this.customValueMap)
emailAddress ?? '',
toDisplayPhoneNumber(servicePhone)
]; ];
},
getEditContactInfoLinkText() {
return this.getCmsContent(
this.widget.contactDetails,
widgetFields.CONTENT_GROUP_WIDGET.FOOTER_TEXT
);
},
recalModalContent() {
const widgetName = 'RecalModal';
return {
headerText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT),
subHeaderText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.SUBHEADER_TEXT),
bodyText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT),
footerButtonText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.FOOTER_TEXT),
image: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.IMAGE)
}
},
recalibrationRequired() {
return this.mainStore.hasRecalibrationPart;
},
customValueMap() {
return {
glassShop: this.getPreferredShopTitle,
contactPhone: toDisplayPhoneNumber(this.mainStore.contactInfo.servicePhone),
contactEmail: this.mainStore.contactInfo.emailAddress
}
} }
}, },
methods: { methods: {
setSections() { setSections() {
const vehicleScenario = useMainStore().isPolicyVehicle
? this.navigationScenarios.EDIT_POLICY_VEHICLE
: this.navigationScenarios.EDIT_VEHICLE;
this.sections = [ this.sections = [
this.getSection( this.getSection(
this.widget.subheader.vehicle, this.getPreferredShopTitle,
this.getVehicleLines,
() => this.navigate(vehicleScenario)
),
// eslint-disable-next-line max-len
this.getSection(
this.widget.subheader.damage,
this.getDamageLines,
() => this.navigate(this.navigationScenarios.EDIT_DAMAGE)
),
this.getSection(
this.widget.subheader.shop,
this.getPreferredShopLines, this.getPreferredShopLines,
() => this.navigate(this.navigationScenarios.EDIT_PREFERRED_SHOP) this.getEditShopLinkText,
() => this.navigate(this.navigationScenarios.EDIT_PREFERRED_SHOP),
), ),
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
this.getSection( this.getSection(
this.widget.subheader.contactInfo, this.getContactInfoTitle,
this.getContactInfoLines, this.getContactInfoLines,
this.getEditContactInfoLinkText,
this.openContactDetailsModal this.openContactDetailsModal
) )
]; ];
}, },
getSection(widgetName, lines, onClick) { getSection(title, lines, editLinkText, onClick) {
return { return {
title: this.getCmsContent( title: title,
widgetName,
widgetFields.TEXT_BLOCK_WIDGET.TEXT
),
lines, lines,
editLinkText,
onClickEdit: onClick onClickEdit: onClick
}; };
}, },
@ -344,7 +319,7 @@ export default {
await submitWorkOrder({ submitType: submitType.TPA }).then(() => { await submitWorkOrder({ submitType: submitType.TPA }).then(() => {
this.navigate(this.navigationScenarios.CLICKED_FORWARD); this.navigate(this.navigationScenarios.CLICKED_FORWARD);
}).catch((submitError) => { }).catch((submitError) => {
useMainStore().setBailout(bailoutMessage.saveSessionError(submitError.data)); this.mainStore.setBailout(bailoutMessage.saveSessionError(submitError.data));
this.navigate( this.navigate(
this.navigationScenarios.SAVE_SESSION_FAILED, this.navigationScenarios.SAVE_SESSION_FAILED,
this.$route, this.$route,
@ -372,6 +347,12 @@ export default {
}, },
openContactDetailsModal() { openContactDetailsModal() {
this.$refs.contactDetailsDrawer.openModal(); this.$refs.contactDetailsDrawer.openModal();
},
openRecalModal() {
this.$refs.recalModal.openModal();
},
closeRecalModal() {
this.$refs.recalModal.closeModal();
} }
} }
}; };
@ -387,26 +368,69 @@ export default {
} }
.tpa-submit { .tpa-submit {
#tpaSubmitOrderDetailsBody { .alert-warning {
p { margin-top: 1.25rem;
font-size: .875rem; margin-bottom: 0rem;
}
}
.tpa-submit__title--line-height {
line-height: map-get($spacers, 6);
} }
.text-color--darker-gray { .tpa-submit-title {
color: $darker-gray; font-size: 1.25rem;
color: $black;
font-weight: 400;
margin-top: 1.25rem;
margin-bottom: .625rem;
} }
.text-color--black { .recal-alert {
margin-bottom: 4rem;
}
b {
font-weight: $font-weight-bold;
color: $black; color: $black;
} }
hr { hr {
opacity: 1; margin: 1.875rem 0rem;
color: $gray-350; }
.fw-bold {
color: $black;
}
.order-details-title {
margin-bottom: .625rem;
}
.modal.recal-modal .modal-dialog {
.modal-header {
justify-content: start;
margin: 0rem;
padding: 1.25rem 1.25rem .625rem 1.25rem;
.modal-title {
font-weight: $font-weight-bolder;
font-size: .875rem;
line-height: 1.25rem;
text-align: start;
justify-content: start;
}
.btn-close {
display: none;
}
}
.modal-body {
padding: 0rem 1.25rem 1.25rem 1.25rem;
b {
font-weight: 600;
}
}
.recal-modal-subheader {
font-weight: $font-weight-bold;
color: $black;
}
.recal-modal-image {
margin: 1.25rem 0rem
}
} }
} }
</style> </style>

View file

@ -197,6 +197,7 @@ export const getDefaultState = () => ({
homePhone: null, homePhone: null,
alternativePhone: null, alternativePhone: null,
servicePhone: null, servicePhone: null,
extension: null,
requestTextUpdates: false, requestTextUpdates: false,
notesForTechnician: '' notesForTechnician: ''
}, },
@ -354,6 +355,7 @@ export const useMainStore = defineStore({
homePhone: s.order.contactInfo.homePhone, homePhone: s.order.contactInfo.homePhone,
alternativePhone: s.order.contactInfo.alternativePhone, alternativePhone: s.order.contactInfo.alternativePhone,
servicePhone: s.order.contactInfo.servicePhone, servicePhone: s.order.contactInfo.servicePhone,
extension: s.order.contactInfo.extension,
requestTextUpdates: s.order.contactInfo.requestTextUpdates ?? false, requestTextUpdates: s.order.contactInfo.requestTextUpdates ?? false,
notesForTechnician: s.order.contactInfo.notesForTechnician notesForTechnician: s.order.contactInfo.notesForTechnician
}), }),
@ -2572,9 +2574,12 @@ export const useMainStore = defineStore({
updatePhoneNumbers(phoneNumbers) { updatePhoneNumbers(phoneNumbers) {
const contact = this.order.contactInfo; const contact = this.order.contactInfo;
console.log('Updating phone numbers with:', phoneNumbers);
console.log('Current contact info before update:', contact);
contact.homePhone = phoneNumbers.home !== undefined ? phoneNumbers.home : contact.homePhone; contact.homePhone = phoneNumbers.home !== undefined ? phoneNumbers.home : contact.homePhone;
contact.alternativePhone = phoneNumbers.alternative !== undefined ? phoneNumbers.alternative : contact.alternativePhone; contact.alternativePhone = phoneNumbers.alternative !== undefined ? phoneNumbers.alternative : contact.alternativePhone;
contact.servicePhone = phoneNumbers.service !== undefined ? phoneNumbers.service : contact.servicePhone; contact.servicePhone = phoneNumbers.service !== undefined ? phoneNumbers.service : contact.servicePhone;
contact.extension = phoneNumbers.extension !== undefined ? phoneNumbers.extension : contact.extension;
}, },
GetExperimentsByUser(userId) { GetExperimentsByUser(userId) {

View file

@ -494,18 +494,21 @@ describe('Store', () => {
const homePhone = getRandomInt(1000000000, 9999999999); const homePhone = getRandomInt(1000000000, 9999999999);
const servicePhone = getRandomInt(1000000000, 9999999999); const servicePhone = getRandomInt(1000000000, 9999999999);
const altPhone = getRandomInt(1000000000, 9999999999); const altPhone = getRandomInt(1000000000, 9999999999);
const extension = getRandomInt(10000, 99999);
// Act // Act
store.updatePhoneNumbers({ store.updatePhoneNumbers({
home: homePhone, home: homePhone,
service: servicePhone, service: servicePhone,
alternative: altPhone alternative: altPhone,
extension: extension
}); });
// Assert // Assert
expect(store.contactInfo.homePhone).toEqual(homePhone); expect(store.contactInfo.homePhone).toEqual(homePhone);
expect(store.contactInfo.servicePhone).toEqual(servicePhone); expect(store.contactInfo.servicePhone).toEqual(servicePhone);
expect(store.contactInfo.alternativePhone).toEqual(altPhone); expect(store.contactInfo.alternativePhone).toEqual(altPhone);
expect(store.contactInfo.extension).toEqual(extension);
}); });
it('All null values => contact info set in store to all nulls', () => { it('All null values => contact info set in store to all nulls', () => {
// Act // Act

View file

@ -226,6 +226,7 @@ export default {
padding: 0rem .625rem; padding: 0rem .625rem;
} }
.btn-collapse { .btn-collapse {
display: flex;
border: none; border: none;
background: none; background: none;
min-width: 1rem; min-width: 1rem;
@ -242,7 +243,7 @@ export default {
} }
} }
a { a {
text-decoration: none; font-weight: $font-weight-normal;
} }
border-color: transparent; border-color: transparent;
.btn-close { .btn-close {