afterpay modal WIP

This commit is contained in:
Katie Kroell 2026-02-18 14:39:08 -05:00
parent 9bc40980d8
commit 7a3dabec43
2 changed files with 268 additions and 1 deletions

View file

@ -0,0 +1,257 @@
<template>
<div class="afterpay-modal-banner" role="alert">
<component
:is="'script'">
src="https://js.squarecdn.com/square-marketplace.js"
async></component>
<div class="afterpay-content">
<span class="afterpay-header" v-html="afterpayHeaderCopy"></span>
<span class="afterpay-amount">{{ afterpayPaymentAmount }}</span>
<span class="afterpay-subheader" v-html="afterpaySubheaderCopy"></span>
<img :src="imageUrl" class="image"/>
<span>. &nbsp;</span>
<a
id="afterpay-learnmore"
href="#"
data-afterpay-modal="en_US"
data-bind="click:afterpayLearnMore"
class="afterpay-learn-more"
>Learn more
</a>
</div>
</div>
</template>
<script>
import {
doesCopyContainTextLink,
splitCopyOnCMSPlaceHolder,
getRouterLinkRouteFromCopy,
getRouterLinkDisplayTextFromCopy,
getExternalLink,
setupModalLinks
} from "@/helpers/cms-content-helper";
import { formatAmountInDollars } from '@/helpers/text-helper.js';
import textLink from "@/ux-components/text-link/text-link";
import modal from "@/digital-components/modal/modal";
import widgetFields from '@/constants/cms-widget-fields.js'; import { useMainStore } from '@/store/index.js';
export default {
name: "afterpay-banner",
components: {
},
props: {
cmsWidgetName: String,
modalWidgetName: String,
totalServicePrice: String
},
setup() {
const mainStore = useMainStore();
return { mainStore };
},
data() {
return {};
},
mounted() {
setupModalLinks(this);
},
methods: {
doesCopyContainTextLink,
splitCopyOnCMSPlaceHolder,
getRouterLinkRouteFromCopy,
getRouterLinkDisplayTextFromCopy,
getExternalLink,
openModal() {
this.modal?.openModal();
},
closeModal() {
this.modal?.closeModal();
},
},
computed: {
imageUrl() {
return this.getCmsContent(this.cmsWidgetName, widgetFields.CONTENT_GROUP_WIDGET.IMAGE);
},
afterpayHeaderCopy() {
return this.getCmsContent(this.cmsWidgetName, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT);
},
afterpaySubheaderCopy() {
return this.getCmsContent(this.cmsWidgetName, widgetFields.CONTENT_GROUP_WIDGET.SUBHEADER_TEXT);
},
modalName() {
return this.modalWidgetName;
},
modal() {
return this.$refs[this.modalName];
},
deductibleValue() {
return this.mainStore.currentDeductible;
},
afterpayPaymentAmount() {
return this.calculateAfterpayPaymentAmount;
},
isDeductibleScenario() {
return this.mainStore.isVerified && this.mainStore.isDeductible;
},
calculateAfterpayPaymentAmount() {
const totalAmount = this.isDeductibleScenario ? this.deductibleValue : this.totalServicePrice;
const afterpayAmount = (totalAmount / 4).toFixed(2);
return formatAmountInDollars(afterpayAmount);
}
}
};
</script>
<style lang="scss" scoped>
.afterpay-modal-banner {
background-color: $blue-100;
justify-content: center;
align-items: center;
padding: 0.5rem 1rem 0.5rem 1rem;
border-radius: 0.25rem;
margin-top: 20px;
}
.afterpay-content {
display: flex;
flex-direction: column;
}
.afterpay-copy {
font-size: 0.875rem;
color: $blue-700;
font-weight: $font-weight-bold;
text-align: center;
flex-direction: column;
}
.image-and-link {
display: flex;
justify-content: center;
align-items: center;
}
.image {
flex-direction: column;
border: 0;
}
:deep(a.learn-more-link) {
color: $blue-700;
fill: $blue-700;
text-decoration: underline;
}
.afterpay-modal {
&.modal.modal-component {
:deep(.modal-dialog) {
margin: 0 1rem;
top: 0;
@include media-breakpoint-up(md) {
width: 100%;
max-width: 840px;
top: 3.4rem;
right: 0;
left: 0;
transform: none;
margin: 0 auto;
padding: 0 1rem;
}
.modal-content {
border-radius: 0.5rem;
margin: 1.5rem 0;
.modal-header.mt-6 {
background-color: $blue-100;
margin-top: 0;
padding: 1.5rem 2rem 1.5rem 1.5rem;
font-family: UrbanistSemibold;
.modal-title.justify-content-center {
// OVERRIDE
justify-content: flex-start;
}
.btn-close {
top: 1.25rem;
right: 1.5rem;
}
}
.afterpay-section {
display: block;
border: 1px solid $gray-200;
border-radius: 0.25rem;
padding: 1rem;
.section-header {
display: flex;
align-items: center;
margin-bottom: 1rem;
img {
width: 40px;
height: 40px;
}
h3 {
font-family: UrbanistBold;
font-size: 1rem;
margin: 0 0 0 0.5rem;
color: $black;
}
}
p {
font-size: 0.75rem;
}
strong {
font-family: UrbanistSemibold;
font-size: 0.875rem;
}
}
.modal-body {
padding: 1.5rem;
.afterpay-sections {
@include media-breakpoint-up(md) {
display: flex;
column-gap: 1rem;
align-items: stretch;
}
.afterpay-section {
margin-bottom: 1rem;
@include media-breakpoint-up(md) {
flex: 0 1 33%;
margin-bottom: 0;
}
&:last-of-type {
margin-bottom: 0;
}
}
}
}
}
&.modal-dialog-centered {
height: auto;
min-height: auto;
}
}
}
:deep(.modal-footer) {
position: relative;
background: $gray-100;
.modal-disclaimer {
font-style: italic;
font-size: 0.75rem;
a {
padding: 0;
line-height: 1.625;
}
}
}
}
</style>

View file

@ -69,6 +69,10 @@
class="d-flex justify-content-center cost mb-0 cost-underline">
{{ formatAmountInDollars(totalServicePrice) }}
</div>
<afterpayModalBanner
v-if="displayAfterpayBanner"
cmsWidgetName="AfterpayModalWidget"
:totalServicePrice="totalServicePrice" />
<buttonMain
ref="buttonMain"
class="full-width-button mt-5 mb-5"
@ -117,6 +121,7 @@ import textBlock from '@/digital-components/text-block/text-block.vue';
import textLink from '@/ux-components/text-link/text-link.vue';
import buttonMain from '@/ux-components/button-main/button-main.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import afterpayModalBanner from '@/layouts/coverage-statement/afterpay-modal-banner/afterpay-modal-banner.vue';
// Import Supporting Files
import {
fetchCmsContentForPage,
@ -151,7 +156,8 @@ export default {
textBlock,
textLink,
siteFooter,
cancelClaimModal
cancelClaimModal,
afterpayModalBanner
},
mixins: [baseFormMixin, vehicleQuestionsMixin],
async beforeRouteEnter(to, from, next) {
@ -337,6 +343,10 @@ export default {
return 'centered-back-button';
}
return '';
},
displayAfterpayBanner() {
return true;
// return (this.isITACQuoteVisible || this.isNoCompQuoteVisible) && this.totalServicePrice > 0;
}
},
watch: {