Visual build of coverage-statement

This commit is contained in:
Chloe Herd 2026-05-18 10:52:17 -04:00
parent 865aeb33bb
commit 9df05e80a1
3 changed files with 214 additions and 4 deletions

View file

@ -4,10 +4,42 @@
<div class="container">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader class="pb-4" cmsWidgetName="FunnelSubHeaderWidget" />
<!--
... Page code goes here.
-->
<!--funnelSubHeader class="pb-4" cmsWidgetName="FunnelSubHeaderWidget" /-->
<div class="my-5" ref="unverified-block">
<funnelSubHeader cmsWidgetName="SubHeaderWidgetUnverified" alignLeft />
<customerInstructions
cmsWidgetName="InstructionsWidgetUnverified"
v-on="{ textLinkClicked: openModalAction }" />
</div>
<div class="my-5" ref="verified-block">
<funnelSubHeader cmsWidgetName="SubHeaderWidgetVerified" alignLeft />
<priceDisplay
cmsWidgetName="PriceWidgetVerified"
:price="deductibleAmount" />
<customerInstructions
cmsWidgetName="InstructionsWidgetVerified"
v-on="{ textLinkClicked: openModalAction }" />
<contentGroupModal ref="OemModal" cmsWidgetName="OemModalWidget" />
<afterpayBreakout
cmsWidgetName="AfterpayBreakoutWidget"
:totalAmount="cashPrice" />
</div>
<div class="my-5" ref="itac-block">
<funnelSubHeader
class="mb-4"
cmsWidgetName="SubHeaderWidgetItac"
alignLeft />
<div class="price-compare">
<priceDisplay
cmsWidgetName="DeductibleWidgetItac"
:price="deductibleAmount" />
<priceDisplay cmsWidgetName="PriceWidgetItac" :price="cashPrice" />
</div>
</div>
<saveProgressModalQuestion
modalWidgetName="SaveProgressModalWidget"
modalName="SaveProgressModal"
pageName="coverage-statement" />
<navbar
cmsWidgetName="FunnelFooterWidget"
ref="navbar"
@ -28,6 +60,12 @@ import { Form } from "vee-validate";
import store from "@/store";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import customerInstructions from "./customer-instructions/customer-instructions.vue";
import priceDisplay from "./price-display/price-display.vue";
import saveProgressModalQuestion from "@/fmg-components/save-progress-modal-question/save-progress-modal-question.vue";
import afterpayBreakout from "../payment-method/afterpay-breakout/afterpay-breakout.vue";
import modal from "@/digital-components/modal/modal";
import contentGroupModal from "@/fmg-components/content-group-modal/content-group-modal.vue";
export default {
name: "coverage-statement",
@ -43,6 +81,11 @@ export default {
funnelHeader,
navbar,
funnelSubHeader,
customerInstructions,
priceDisplay,
saveProgressModalQuestion,
afterpayBreakout,
contentGroupModal,
},
// Ensure CMS content is fetched during route navigation without depending on `to`/`from`
async beforeRouteEnter(to, from, next) {
@ -98,6 +141,38 @@ export default {
arePagePrerequisitesValid() {
return true;
},
openModalAction(modalName) {
this.$refs[modalName]?.openModal();
},
},
computed: {
deductibleAmount() {
return this.$store.getters.order.policy.currentDeductible;
},
cashPrice() {
const lineItems = this.$store.getters.order.lineItems;
const lineItemsFlattened = [
...(lineItems?.glassParts ?? []),
...(lineItems?.promos ?? []),
...(lineItems?.supportingItems ?? []),
...(lineItems?.vaps ?? []),
];
const price = this.getTotalPriceOfAllLineItemsAndChildParts(lineItemsFlattened, false);
return price;
},
},
};
</script>
<style lang="scss">
.price-compare {
display: flex;
> :not(:last-child) {
padding-right: 1em;
margin-right: 1em;
border-right: 2px solid $gray-300;
}
}
</style>

View file

@ -0,0 +1,82 @@
<template>
<div>
<div>
<strong>
{{ headerText }}
</strong>
</div>
<div>
<ol>
<li v-for="block in instructionBlocks" :key="block">
<span v-for="token in block" :key="token">
<span v-if="doesCopyContainTextLink(token)" class="link">
<textLink
linkType="text"
:text="getRouterLinkDisplayTextFromCopy(token)"
href="#!"
@click-event="
$emit('textLinkClicked', getRouterLinkRouteFromCopy(token))
"
:data-bs-target="'#' + getRouterLinkRouteFromCopy(token)" />
</span>
<span v-else v-html="token" class="copy"></span>
</span>
</li>
</ol>
</div>
</div>
</template>
<script>
import textLink from "@/ux-components/text-link/text-link";
import {
doesCopyContainTextLink,
splitCopyOnCMSPlaceHolder,
getRouterLinkRouteFromCopy,
getRouterLinkDisplayTextFromCopy,
getExternalLink,
} from "@/helpers/cms-content-helper";
export default {
name: "customer-instructions",
data() {
return {};
},
props: {
cmsWidgetName: String,
},
methods: {
doesCopyContainTextLink,
splitCopyOnCMSPlaceHolder,
getRouterLinkRouteFromCopy,
getRouterLinkDisplayTextFromCopy,
getExternalLink,
},
computed: {
headerText() {
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
},
instructionBlocks() {
const answers = this.getCmsContent(this.cmsWidgetName, "Answers");
const instructionBlocksRaw = answers.map((ans) => ans.Text);
const instructionBlocksAsTokens = instructionBlocksRaw.map((raw) =>
splitCopyOnCMSPlaceHolder(raw)
);
return instructionBlocksAsTokens;
},
},
components: {
textLink,
},
};
</script>
<style lang="scss" scoped>
:deep(li) {
margin-top: 0.5em;
}
</style>

View file

@ -0,0 +1,53 @@
<template>
<div class="mb-4">
<div>
<strong>
{{ headerText }}
</strong>
</div>
<div class="price" :class="markAsHigher ? 'red' : 'green'">
{{ priceText }}
</div>
</div>
</template>
<script>
export default {
name: "price-display",
data() {
return {};
},
props: {
cmsWidgetName: String,
price: Number,
markAsHigher: Boolean,
},
methods: {},
computed: {
headerText() {
return this.getCmsContent(this.cmsWidgetName, "Text");
},
priceText() {
const toFixed = this.price.toFixed(2);
return `$${toFixed}`;
},
},
components: {},
};
</script>
<style lang="scss">
.price {
font-size: 1.5em;
display: inline-block;
&.green {
color: $green-700;
border-bottom: 3px solid $red-800;
}
&.red {
color: $red-700;
border-bottom: 3px solid $red-800;
}
}
</style>