Adding tpa submit page

This commit is contained in:
Michaela Brydon 2023-12-04 18:49:24 -05:00
parent fe3f1fb86c
commit ef49dadbb2
10 changed files with 307 additions and 141 deletions

View file

@ -4,6 +4,7 @@
class="tpa-toggle" class="tpa-toggle"
:class="[isDetailVisible ? 'active' : '']" :class="[isDetailVisible ? 'active' : '']"
@click="handleClickToggle"></div> @click="handleClickToggle"></div>
<button>Edit Me!</button>
<textLink <textLink
id="moreDetails" id="moreDetails"
linkType="text" linkType="text"

View file

@ -0,0 +1,33 @@
<template>
<div class="deductible-box d-flex justify-content-between align-items-center py-2 px-5">
<p class="deductible-box__text">
Deductible
</p>
<p class="deductible-box__text">
{{ value }}
</p>
</div>
</template>
<script>
export default {
name: 'deductible-box',
props: {
value: String
}
};
</script>
<style lang="scss" scoped>
.deductible-box {
background-color: $green;
}
.deductible-box__text {
color: white;
font-weight: 500;
margin: 0;
}
</style>

View file

@ -1,18 +1,16 @@
<template> <template>
<div class="py-3"> <div class="review-block">
<div class="d-flex"> <div class="d-flex justify-content-between">
<textBlock <p class="review-block__header small-strong pb-1">
:cmsWidgetName="headerCmsWidgetName" {{ customHeaderText }}
:customText="customHeaderText" </p>
typeStyle="body small bold dark"
marginTopSizeOverride="0" />
<textLink <textLink
linkType="textSmall" linkType="textSmall"
text="Edit" :text="editLinkText"
class="ml-auto"
useLoadingModal useLoadingModal
href="javascript:void(0)" href="javascript:void(0)"
@click-event="linkClicked"> class="link"
@clickEvent="editClicked">
<template <template
v-if="editScreenReaderTextCmsWidgetName" v-if="editScreenReaderTextCmsWidgetName"
#after-text> #after-text>
@ -20,50 +18,54 @@
</template> </template>
</textLink> </textLink>
</div> </div>
<!-- how about a p instead of div with html --> <p
<div v-for="line in lines"
v-for="line in content"
:key="line" :key="line"
class="small review-block-content" class="small review-block__body--line">
data-test="contentLine" {{ line }}
v-html="line"></div> </p>
</div>
<div>
<!-- TODO title -->
<!-- TODO edit button -->
<!-- TODO lines -->
</div> </div>
</template> </template>
<script> <script>
import textBlock from "@/digital-components/text-block/text-block"; import textLink from '@/ux-components/text-link/text-link.vue';
import textLink from "@/ux-components/text-link/text-link";
export default { export default {
name: 'review-block', name: 'review-block',
components: [ components: { textLink },
textBlock,
textLink
],
props: { props: {
headerCmsWidgetName: String, headerCmsWidgetName: String,
customHeaderText: String, customHeaderText: String,
// Specifically an array of strings.
content: Array,
editScreenReaderTextCmsWidgetName: String, editScreenReaderTextCmsWidgetName: String,
lines: Array lines: Array
}, },
emits: ['click-edit'],
data() { data() {
return { return {
editLinkText: 'Edit'
}; };
}, },
computed: {
},
methods: { methods: {
editClicked() {
this.$emit('click-edit');
}
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.review-block {
:deep(p) {
margin: 0;
}
.review-block__header {
color: $black;
}
.review-block__body--line {
color: $gray-600;
}
.link {
text-underline-offset: 1px;
}
}
</style> </style>

View file

@ -1,7 +1,8 @@
<template> <template>
<Form <Form
ref="theForm" ref="tpaSubmitFormRef"
v-slot="{ meta }" v-slot="{ meta }"
class="tpa-submit"
@submit="onSubmit" @submit="onSubmit"
@invalidSubmit="onInvalidSubmit"> @invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles"> <div class="page-container-grouped-styles">
@ -9,75 +10,79 @@
<siteHeader <siteHeader
ref="siteHeader" ref="siteHeader"
:cmsWidgetName="widget.siteHeader" /> :cmsWidgetName="widget.siteHeader" />
<div class="container-fluid px-6"> <div class="px-5">
<vehicleBanner <vehicleBanner
ref="vehicleBanner"
:cmsWidgetName="widget.vehicleBanner" :cmsWidgetName="widget.vehicleBanner"
:displayGenericVehicleImage="false" /> :displayGenericVehicleImage="false"
class="mt-5" /> <!-- TODO fix styling -->
<textBlock <textBlock
:customText="subHeaderTitle" :customText="subHeaderTitle"
typeStyle="h5"
justifyText="center" justifyText="center"
class="dark-header mt-4" /> :marginTopSizeOverride="4"
class="text-color--black fs-5 tpa-submit__title--line-height" />
<textBlock <textBlock
:customText="subHeaderBody" id="tpaSubmitSubHeaderBodyOne"
typeStyle="body" :customText="subHeaderBodyOne"
justifyText="left" class="small text-color--darker-gray" />
margin="mt-0 mb-2" /> <textBlock
id="tpaSubmitSubHeaderBodyTwo"
:customText="subHeaderBodyTwo"
class="mb-4 small text-color--darker-gray" />
<buttonMain <buttonMain
ref="buttonMain" ref="buttonMain"
isPrimary isPrimary
:buttonText="forwardButtonText" :buttonText="forwardButtonText"
loaderColor="white" loaderColor="white"
class="mb-2 w-100" class="w-100 mb-4"
@clickEvent="forwardButtonAction" /> @clickEvent="forwardButtonAction" />
<hr /> <hr class="mb-0" />
<div id="serviceSummarySection">
<textBlock <textBlock
customText="Service Summary" id="tpaSubmitServiceSummaryTitle"
typeStyle="label bold" :customText="serviceSummaryText"
justifyText="justify-text-left" :marginTopSizeOverride="4"
margin="mt-0" class="fw-bold fs-1 lh-lg text-color--black" />
class="dark-header" /> <div class="px-4 my-3">
<div
<!-- TODO Service Summary title --> v-for="(section, index) in sections"
<!-- TODO Vehicle piece --> :key="section.title">
<!-- TODO Damage piece --> <hr
<!-- TODO Preferred Shop piece --> v-if="index !== 0"
<!-- TODO Contact details piece --> class="my-3" />
<!-- TODO Order details title --> <reviewBlock
<!-- TODO Order details body --> :id="'review-block-' + index"
<!-- TODO Green Deductible Rectangle --> :customHeaderText="section.title"
:lines="section.lines"
@clickEdit="() => section.onClickEdit()" />
</div>
</div>
</div>
<hr class="mb-0" />
<div id="submitOrderDetailsSection">
<textBlock
id="tpaSubmitOrderDetailsTitle"
:customText="orderDetailsTitle"
:marginTopSizeOverride="4"
class="fw-bold text-color--black" />
<textBlock
id="tpaSubmitOrderDetailsBody"
:customText="orderDetailsBody"
:marginTopSizeOverride="4"
class="mb-4 px-4 small text-color--darker-gray" />
<deductibleBox :value="deductibleBoxValue" />
</div>
<siteFooter <siteFooter
ref="siteFooter" ref="siteFooter"
class="mt-5" class="mt-5"
cmsWidgetName="SiteFooterWidget" :cmsWidgetName="widget.footer"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@backClicked="navigateBack" @backClicked="backButtonAction"
@forwardClicked="forwardButtonAction" /> @forwardClicked="forwardButtonAction" />
</div> </div>
</div> </div>
</div> </div>
</Form> </Form>
<!-- <Form
ref="theForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles">
<div class="fade-on-route-transition position-relative">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
<div class="container-fluid pb-2 submit">
<p>Placeholder for TPA-Submit</p>
<siteFooter
ref="siteFooter"
cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction"
@backClicked="backButtonAction" />
</div>
</div>
</div>
</Form> -->
</template> </template>
<script> <script>
// Components // Components
@ -85,14 +90,46 @@ import siteHeader from '@/iss-components/site-header/site-header.vue';
import buttonMain from '@/ux-components/button-main/button-main.vue'; import buttonMain from '@/ux-components/button-main/button-main.vue';
import textBlock from '@/digital-components/text-block/text-block.vue'; import textBlock from '@/digital-components/text-block/text-block.vue';
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue'; import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
import reviewBlock from '@/layouts/tpa-submit/review-block/review-block.vue';
import deductibleBox from '@/layouts/tpa-submit/deductible-box/deductible-box.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-helper';
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';
const VERIFYING_COVERAGE = 'Verifying coverage';
// TODO move functions to general location
function getStringWithCustomValues(str, customValueMap) {
let newString = str;
Object.entries(customValueMap).forEach((key, value) => {
newString = newString.replaceAll(`{custom:${key}}`, value);
});
return newString;
}
function getDisplayPhoneNumber(phoneNumber) {
return phoneNumber;
}
function getTitleCase(str) {
return str;
}
// TODO more elaborate
function getAddressString(addressLine1, addressLine2, city, state, zipCode) {
return `${this.getTitleCase(addressLine1)}, ${this.getTitleCase(addressLine2)}, `
+ `${this.getTitleCase(city)}, ${state} ${zipCode}`;
}
// TODO make round two decimal places and work for both strings and numbers
function getDisplayDollars(amount) {
return `$${amount}`;
}
export default { export default {
name: 'tpa-submit', name: 'tpa-submit',
@ -101,81 +138,150 @@ export default {
vehicleBanner, vehicleBanner,
textBlock, textBlock,
buttonMain, buttonMain,
reviewBlock,
deductibleBox,
siteFooter, siteFooter,
// eslint-disable-next-line vue/no-reserved-component-names // eslint-disable-next-line vue/no-reserved-component-names
Form Form
}, },
mixins: [BaseFormMixin], mixins: [BaseFormMixin],
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); const cmsContent = await fetchCmsContentForPage(to.query.issPage);
const promiseResultMap = [
{
resultKey: 'cmsContent',
promise: cmsContentPromise
}
];
const resultMap = await settleAllPromises(promiseResultMap);
next((vm) => { next((vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(cmsContent);
vm.setSections();
}); });
}, },
data() { data() {
const { companyName } = useMainStore().order.serviceLocation.provider;
return { return {
sections: [],
widget: { widget: {
siteHeader: 'SiteHeaderWidget', siteHeader: 'SiteHeaderWidget',
siteSubHeader: 'SiteSubHeaderWidget', siteSubHeader: 'SiteSubHeaderWidget',
serviceSummary: 'ServiceSummaryContent',
vehicleBanner: 'VehicleBannerWidget', vehicleBanner: 'VehicleBannerWidget',
subheader: {
vehicle: 'VehicleSubTitle',
damage: 'DamageSubTitle',
shop: 'PreferredShopSubTitle',
contactInfo: 'ContactDetailsSubTitle'
},
orderDetails: 'OrderDetailsContent',
footer: 'SiteFooterWidget' footer: 'SiteFooterWidget'
}, },
widgetFields companyName,
customValueMap: {
glassShop: companyName
}
}; };
}, },
computed: { computed: {
subHeaderTitle() { subHeaderTitle() {
return this.getCmsContent(this.widget.siteSubHeader, 'SubHeaderText'); return this.getCmsContent(this.widget.siteSubHeader, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT);
}, },
subHeaderBody() { subHeaderBodyOne() {
const initial = this.getCmsContent(this.widget.siteSubHeader, 'SecondaryText'); return this.getCmsContent(this.widget.siteSubHeader, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
const x = initial.replace('{custom:glassShop}', 'Random Shop Name'); },
return x; subHeaderBodyTwo() {
// return this.getCmsContent(this.widget.siteSubHeader, 'SecondaryText'); const cmsContent = this.getCmsContent(this.widget.siteSubHeader, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2);
return this.getStringWithCustomValues(cmsContent, this.customValueMap);
},
serviceSummaryText() {
return this.getCmsContent(this.widget.serviceSummary, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
},
orderDetailsTitle() {
return this.getCmsContent(this.widget.orderDetails, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT);
},
orderDetailsBody() {
return this.getCmsContent(this.widget.orderDetails, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
},
deductibleBoxValue() {
const { isVerified } = useMainStore().order.payment.insuranceCoverage;
const { currentDeductible } = useMainStore().order;
return isVerified ? this.getDisplayDollars(currentDeductible) : VERIFYING_COVERAGE;
}, },
forwardButtonText() { forwardButtonText() {
return this.getCmsContent(this.widget.footer, 'ForwardButtonText'); return this.getCmsContent(this.widget.footer, widgetFields.FOOTER_WIDGET.FORWARD_BUTTON_TEXT);
},
getVehicleLines() {
const { year, make, model } = useMainStore().order.vehicle;
return [`${year} ${make} ${model}`];
},
getDamageLines() {
return [useMainStore().order.policy.damageCause];
},
getPreferredShopLines() {
const { phoneNumber, address } = useMainStore().order.serviceLocation.provider;
const { streetAddress, city, state, zipCode } = address;
const displayAddress = this.getAddressString(streetAddress, '', city, state, zipCode);
const displayPhoneNumber = this.getDisplayPhoneNumber(phoneNumber);
return [this.companyName, displayAddress, displayPhoneNumber];
},
getContactInfoLines() {
const { firstName, lastName, emailAddress, phoneNumber } = useMainStore().order.contactInfo;
return [
`${firstName} ${lastName}`,
emailAddress,
this.getDisplayPhoneNumber(phoneNumber)
];
} }
// getSubheaderTextFromCms(cmsWidgetName) {
// const subHeader = this.getCmsContent(cmsWidgetName, 'SubHeaderText');
// console.log(JSON.stringify(subHeader));
// return this.processIfStatements(subHeader, 'custom', this.getCustomValueFromString);
// }
}, },
methods: methods:
{ {
setSections() {
this.sections = [
this.getSection(this.widget.subheader.vehicle, this.getVehicleLines, this.navigationScenarios.EDIT_VEHICLE),
this.getSection(this.widget.subheader.damage, this.getDamageLines, this.navigationScenarios.EDIT_DAMAGE),
this.getSection(this.widget.subheader.shop, this.getPreferredShopLines, this.navigationScenarios.EDIT_PREFERRED_SHOP),
// eslint-disable-next-line max-len
this.getSection(this.widget.subheader.contactInfo, this.getContactInfoLines, this.navigationScenarios.EDIT_CONTACT_DETAILS)
];
},
getSection(widgetName, lines, scenario) {
return {
title: this.getCmsContent(widgetName, widgetFields.TEXT_BLOCK_WIDGET.TEXT),
lines,
onClickEdit: this.getNavigateByScenarioMethod(scenario)
};
},
backButtonAction() { backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); this.navigate(this.navigationScenarios.CLICKED_BACK);
}, },
forwardButtonAction() { forwardButtonAction() {
this.$router.navigate( this.navigate(this.navigationScenarios.CLICKED_FORWARD);
this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
}, },
getCustomValueFromString(str) { getNavigateByScenarioMethod(scenario) {
console.log(`string val: ${str}`); return () => this.navigate(scenario);
switch (str) { },
case 'glassShop': navigate(scenario) {
return 'Fake Glass Shop'; this.$router.navigate(scenario, this.$route);
default: },
return null; getStringWithCustomValues,
} getDisplayPhoneNumber,
} getTitleCase,
getAddressString,
getDisplayDollars
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.submit {
margin-bottom:0.75rem; .tpa-submit__title--line-height {
line-height: map-get($spacers, 6);
}
.text-color--darker-gray {
color: $darker-gray
}
.text-color--black {
color: $black;
}
hr {
opacity: 1;
color: $gray-350
} }
</style> </style>

View file

@ -68,6 +68,12 @@ const navigationScenarios = Object.freeze({
CLICKED_FORWARD_WITH_SAFELITE_SHOP: 'CLICKED_FORWARD_WITH_SAFELITE_SHOP', CLICKED_FORWARD_WITH_SAFELITE_SHOP: 'CLICKED_FORWARD_WITH_SAFELITE_SHOP',
CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP: 'CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP', CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP: 'CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP',
// TPA Submit
EDIT_VEHICLE: 'EDIT_VEHICLE',
EDIT_DAMAGE: 'EDIT_DAMAGE',
EDIT_PREFERRED_SHOP: 'EDIT_PREFERRED_SHOP',
EDIT_CONTACT_DETAILS: 'EDIT_CONTACT_DETAILS',
// Provider Preference // Provider Preference
CLICKED_FORWARD_WITH_SAFELITE: 'CLICKED_FORWARD_WITH_SAFELITE', CLICKED_FORWARD_WITH_SAFELITE: 'CLICKED_FORWARD_WITH_SAFELITE',
CLICKED_FORWARD_WITH_TPA_ENABLED: 'CLICKED_FORWARD_WITH_TPA_ENABLED', CLICKED_FORWARD_WITH_TPA_ENABLED: 'CLICKED_FORWARD_WITH_TPA_ENABLED',

View file

@ -637,6 +637,22 @@ const routingTable = () => [
{ {
issPageValue: issPageValues.TPA_SUBMIT, issPageValue: issPageValues.TPA_SUBMIT,
maps: [ maps: [
{
scenario: navigationScenarios.EDIT_VEHICLE,
destinationIssPageValue: issPageValues.VEHICLE_SELECTION
},
{
scenario: navigationScenarios.EDIT_DAMAGE,
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
},
{
scenario: navigationScenarios.EDIT_PREFERRED_SHOP,
destinationIssPageValue: issPageValues.PROVIDER_PREFERENCE
},
{
scenario: navigationScenarios.EDIT_CONTACT_DETAILS,
destinationIssPageValue: issPageValues.CONTACT_DETAILS
},
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.TPA_SEARCH destinationIssPageValue: issPageValues.TPA_SEARCH

View file

@ -115,7 +115,9 @@ const getDefaultState = () => ({
state: null, state: null,
zipCode: null, zipCode: null,
zipCodeCtu: null zipCodeCtu: null
} },
companyName: null, // TODO set
phoneNumber: null // TODO set
} }
}, },
lineItems: { lineItems: {

View file

@ -51,6 +51,12 @@ h6,
font-weight: 400; font-weight: 400;
} }
.small-strong {
font-size: .875rem;
line-height: 1.7;
font-weight: 500;
}
label, label,
.label { .label {
font-size: 1rem; font-size: 1rem;
@ -63,16 +69,4 @@ caption,
font-size: .75rem; font-size: .75rem;
line-height: 1.7; line-height: 1.7;
font-weight: 400; font-weight: 400;
}
// Font size
.fs-5 {
line-height: 2;
}
.fs-6 {
font-size: 1rem !important;
line-height: 1.4;
font-weight: 500;
} }

View file

@ -52,6 +52,7 @@ $yellow-900: #331a00;
$gray-100: #f5f5f5; // Used in theme $gray-100: #f5f5f5; // Used in theme
$gray-200: #e3e4e4; // Used in theme $gray-200: #e3e4e4; // Used in theme
$gray-300: #d2d4d4; $gray-300: #d2d4d4;
$gray-350: #b3b4b5; // Used for hr
$gray: #b0b3b3; // Default Gray $gray: #b0b3b3; // Default Gray
$gray-500: #8e9292; // Used in theme $gray-500: #8e9292; // Used in theme
$gray-550: #727676; // Used in theme $gray-550: #727676; // Used in theme
@ -123,9 +124,18 @@ $font-family-base: $font-family-sans-serif;
$font-family-code: $font-family-monospace; $font-family-code: $font-family-monospace;
$font-size-base: 1rem; // Assumes the browser default, typically `16px` $font-size-base: 1rem; // Assumes the browser default, typically `16px`
//Headings
$h1-font-size: $font-size-base * 3;
$h2-font-size: $font-size-base * 2.625;
$h3-font-size: $font-size-base * 2;
$h4-font-size: $font-size-base * 1.625;
$h5-font-size: $font-size-base * 1.25;
$h6-font-size: $font-size-base * 0.875;
//Custom Font size (extra small) //Custom Font size (extra small)
$font-size-xsm: $font-size-base * 0.75; $font-size-xsm: $font-size-base * 0.75;
$font-sizes: ( $font-sizes: (
5: $h5-font-size,
7: $font-size-xsm, 7: $font-size-xsm,
); );
@ -136,13 +146,6 @@ $font-weight-normal: 400;
$font-weight-bold: 500; $font-weight-bold: 500;
$font-weight-bolder: bolder; $font-weight-bolder: bolder;
//Headings
$h1-font-size: $font-size-base * 3;
$h2-font-size: $font-size-base * 2.625;
$h3-font-size: $font-size-base * 2;
$h4-font-size: $font-size-base * 1.625;
$h5-font-size: $font-size-base * 1.25;
$h6-font-size: $font-size-base * 0.875;
//Border Radius //Border Radius
// Helper classes are rounded, rounded-1, rounded-2, rounded-3 // Helper classes are rounded, rounded-1, rounded-2, rounded-3
@ -173,6 +176,9 @@ $spacers: (
8: $spacer * 3, 8: $spacer * 3,
); );
//Line Height
//Grid breakpoints //Grid breakpoints
$grid-breakpoints: ( $grid-breakpoints: (
xs: 0, xs: 0,