Merge pull request #1683 from Safelite/feature/csr-1763

Feature/csr 1763
This commit is contained in:
chloeherdsafelite 2024-01-10 14:10:54 -05:00 committed by GitHub
commit 6f1ebb844b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 0 deletions

View file

@ -0,0 +1,111 @@
<template>
<div class="alert fade show my-2 py-2 border-0 alert-info" role="alert">
<component :is="'script'" src="https://js.afterpay.com/afterpay-1.x.js" async></component>
<div class="mx-4 my-0 fw-bold alert-heading">
<span v-for="token in afterpayCopyTokens" :key="token">
<span v-if="isAfterpayPriceToken(token)">{{ afterpayPrice }}</span>
<span v-else-if="isInlineImageToken(token)">
<img v-if="hasImage" :src="imageUrl" :alt="getInlineAltText(token)" />
<span v-else>{{ getInlineAltText(token) }}</span>
</span>
<span v-else>
{{ token }}
</span>
</span>
</div>
<div class="mx-4 my-0 fw-bold alert-heading">
<a
id="afterpay-learnmore"
href="#"
data-afterpay-modal="en_US-safelite"
data-bind="click:afterpayLearnMore">
{{ modalCopy }}
</a>
</div>
</div>
</template>
<script>
import { splitCopyOnCMSPlaceHolder } from "@/helpers/cms-content-helper";
import baseMixin from "@/mixins/base-mixin.js";
const INLINE_IMAGE_TOKEN = "custom:inlineImage";
const AFTERPAY_PRICE_TOKEN = "custom:afterpayPrice";
function isInlineImageToken(token) {
return token.includes(INLINE_IMAGE_TOKEN);
}
function isAfterpayPriceToken(token) {
return token.includes(AFTERPAY_PRICE_TOKEN);
}
function getInlineAltText(token) {
const innerTokens = token.split(",");
return innerTokens[1] ?? "";
}
export default {
name: "afterpay-modal-banner",
props: {
cmsWidgetName: String,
lineItems: Array,
},
data() {
return {};
},
methods: {
isInlineImageToken,
isAfterpayPriceToken,
getInlineAltText,
},
computed: {
nullSafeLineItems() {
return this.lineItems ?? [];
},
imageUrl() {
return this.getCmsContent(this.cmsWidgetName, "Image");
},
hasImage() {
return !!this.imageUrl;
},
afterpayCopyTokens() {
return splitCopyOnCMSPlaceHolder(this.getCmsContent(this.cmsWidgetName, "HeaderText"));
},
modalCopy() {
return this.getCmsContent(this.cmsWidgetName, "SubheaderText");
},
afterpayPrice() {
const price = baseMixin.methods.getTierOnePackagePrice(
baseMixin.methods.filterOutFees(this.nullSafeLineItems)
);
const adjusted = (price / 4).toFixed(2);
return `$${adjusted}`;
},
},
components: {},
};
</script>
<style lang="scss" scoped>
.alert {
padding: 0.675rem 0;
&.alert-info {
background-color: $blue-100;
.alert-heading {
color: $blue-700;
}
svg {
fill: $blue-700;
width: 1rem;
height: 1rem;
}
}
& .alert-heading {
font-size: 0.875rem;
}
}
</style>

View file

@ -34,6 +34,11 @@
validationRules="option-required"
isRequired />
<afterpayModalBanner
v-if="!isInsuranceSelected"
cmsWidgetName="AfterpayModalWidget"
:lineItems="availableLineItems" />
<textBlock
cmsWidgetName="quoteDisclaimer"
justifyText="left"
@ -68,6 +73,7 @@ import servicePackageQuestion from "./service-package-question/service-package-q
import textBlock from "@/digital-components/text-block/text-block";
import contentGroupModal from "@/fmg-components/content-group-modal/content-group-modal";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
import afterpayModalBanner from "@/layouts/quote/afterpay-modal-banner/afterpay-modal-banner";
import baseMixin from "@/mixins/base-mixin.js";
import vehicleQuestionsMixin from "../../mixins/vehicle-questions-mixin";
import { settleAllPromises } from "@/helpers/layout-helper";
@ -315,6 +321,7 @@ export default {
servicePackageQuestion,
contentGroupModal,
loadingModal,
afterpayModalBanner,
},
};
</script>