315 lines
9.2 KiB
Vue
315 lines
9.2 KiB
Vue
<template>
|
|
<div class="afterpay-modal-banner" role="alert">
|
|
<div>
|
|
<span
|
|
class="callout"
|
|
v-for="token in headerCopyTokens"
|
|
:key="token"
|
|
v-html="token"></span>
|
|
</div>
|
|
<div>
|
|
<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 v-html="token"></span>
|
|
</span>
|
|
<span class="nbsp"> </span>
|
|
<textLink
|
|
linkType="text"
|
|
:text="bannerCta"
|
|
href="javascript:void(0)"
|
|
@click-event="openModal" />
|
|
</div>
|
|
</div>
|
|
<modal
|
|
:ref="modalName"
|
|
class="afterpay-modal"
|
|
:headerText="modalHeaderText"
|
|
:isFooterButtonSuppressed="true">
|
|
<template v-slot:modal-header-slot>
|
|
<span>{{ modalSubHeaderText }}</span>
|
|
</template>
|
|
<template v-slot>
|
|
<span class="afterpay-sections">
|
|
<span
|
|
v-for="section in afterpaySectionsContent"
|
|
:key="section"
|
|
class="afterpay-section">
|
|
<span class="section-header">
|
|
<img v-if="section.AnswerImageUrl" :src="section.AnswerImageUrl" />
|
|
<h3 v-if="section.Text" v-html="section.Text"></h3>
|
|
</span>
|
|
<span v-html="section.content"></span>
|
|
</span>
|
|
</span>
|
|
</template>
|
|
<template v-slot:modal-footer-slot>
|
|
<p class="modal-disclaimer" v-html="modalDisclaimerText"></p>
|
|
</template>
|
|
</modal>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
doesCopyContainTextLink,
|
|
splitCopyOnCMSPlaceHolder,
|
|
getRouterLinkRouteFromCopy,
|
|
getRouterLinkDisplayTextFromCopy,
|
|
getExternalLink,
|
|
splitCMSCopyOnBR,
|
|
} from "@/helpers/cms-content-helper";
|
|
import textLink from "@/ux-components/text-link/text-link";
|
|
import modal from "@/digital-components/modal/modal";
|
|
|
|
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-banner",
|
|
props: {
|
|
cmsWidgetName: String,
|
|
modalWidgetName: String,
|
|
},
|
|
data() {
|
|
return {};
|
|
},
|
|
methods: {
|
|
isInlineImageToken,
|
|
isAfterpayPriceToken,
|
|
getInlineAltText,
|
|
doesCopyContainTextLink,
|
|
splitCopyOnCMSPlaceHolder,
|
|
getRouterLinkRouteFromCopy,
|
|
getRouterLinkDisplayTextFromCopy,
|
|
getExternalLink,
|
|
openModal() {
|
|
this.modal?.openModal();
|
|
},
|
|
closeModal() {
|
|
this.modal?.closeModal();
|
|
},
|
|
},
|
|
computed: {
|
|
imageUrl() {
|
|
return this.getCmsContent(this.cmsWidgetName, "Image");
|
|
},
|
|
hasImage() {
|
|
return !!this.imageUrl;
|
|
},
|
|
headerCopyTokens() {
|
|
return splitCMSCopyOnBR(this.getCmsContent(this.cmsWidgetName, "HeaderText"));
|
|
},
|
|
afterpayCopyTokens() {
|
|
return splitCopyOnCMSPlaceHolder(this.getCmsContent(this.cmsWidgetName, "BodyText"));
|
|
},
|
|
bannerCta() {
|
|
return this.getCmsContent(this.cmsWidgetName, "FooterText");
|
|
},
|
|
modalHeaderText() {
|
|
return this.getCmsContent(this.modalWidgetName, "HeaderText");
|
|
},
|
|
modalDisclaimerText() {
|
|
return this.getCmsContent(this.modalWidgetName, "BodyText2");
|
|
},
|
|
modalName() {
|
|
return this.modalWidgetName;
|
|
},
|
|
modal() {
|
|
return this.$refs[this.modalName];
|
|
},
|
|
afterpaySectionsContent() {
|
|
const sections = this.getCmsContent("AfterpayModalSectionsWidget", "Answers");
|
|
if (!sections) return [];
|
|
sections.forEach((section) => {
|
|
const sectionContent = this.getCmsContent(section.Name, "BodyText");
|
|
section["content"] = sectionContent;
|
|
});
|
|
return sections;
|
|
},
|
|
},
|
|
components: {
|
|
textLink,
|
|
modal,
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.afterpay-modal-banner {
|
|
display: flex;
|
|
flex-direction: column;
|
|
background-color: $blue-150;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 1rem;
|
|
border-radius: 1rem;
|
|
@include media-breakpoint-up(md) {
|
|
flex-direction: row;
|
|
}
|
|
|
|
.callout {
|
|
font-family: UrbanistSemibold, Arial, Helvetica, sans-serif;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
> div:first-of-type {
|
|
display: flex;
|
|
color: $black;
|
|
font-size: $font-size-20;
|
|
line-height: 2rem;
|
|
@include media-breakpoint-down(md) {
|
|
border-bottom: 1px solid;
|
|
padding-bottom: 0.5rem;
|
|
width: 100%;
|
|
justify-content: center;
|
|
|
|
> span:first-of-type {
|
|
margin-right: 0.25rem;
|
|
}
|
|
}
|
|
@include media-breakpoint-up(md) {
|
|
flex-direction: column;
|
|
border-right: 1px solid;
|
|
padding-right: 1rem;
|
|
}
|
|
}
|
|
|
|
> div:last-of-type {
|
|
color: $gray-650;
|
|
text-align: left;
|
|
|
|
@include media-breakpoint-down(md) {
|
|
padding-top: 1rem;
|
|
}
|
|
@include media-breakpoint-up(md) {
|
|
padding-left: 1rem;
|
|
}
|
|
}
|
|
}
|
|
|
|
.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>
|