DigitalConsumer.FixMyGlass/src/experiment-components/service-package-radio.vue

498 lines
17 KiB
Vue

<template>
<baseInputButton v-bind="$props" @buttonClicked="handleAnswerChange" v-model="selectedValue">
<div
class="package-label pricing-by-day-pkg-lbl"
:class="[
this.buttonLabelSubCopy ? 'has-subheader' : '',
!this.additionalButtonData.servicePackageDiscount ? 'adjust-top' : '',
]"
for="testradio">
<div class="package-specs">
<div v-if="this.additionalButtonData.servicePackageDiscount" class="row">
<div class="col md-6">
<p class="m-0">
<span v-html="this.buttonLabel"></span>
</p>
<p
class="sub-label m-0"
v-if="this.buttonLabelSubCopy"
v-html="this.buttonLabelSubCopy"></p>
</div>
<span class="col md-6 service-package-discount-pricing-by-day">
<div>
<span class="caption pricing-by-day">as low as</span>
<div
class="strikethrough-discount-price"
v-if="shouldDisplayStrikeThroughPrice"
v-html="this.additionalButtonData.strikeThroughPrice"></div>
<div class="discount-price" v-html="getDisplayPrice"></div>
</div>
</span>
</div>
<div v-else>
<p class="m-0">
<span v-html="this.buttonLabel"></span>
<span class="pricing-info-pricing-by-day">
<span class="caption pricing-by-day">as low as</span>
<span
class="strikethrough-price"
v-if="shouldDisplayStrikeThroughPrice"
v-html="this.additionalButtonData.strikeThroughPrice"></span>
<span v-html="getDisplayPrice"></span>
</span>
</p>
<p
class="sub-label m-0"
v-if="this.buttonLabelSubCopy"
v-html="this.buttonLabelSubCopy"></p>
</div>
<div class="hide-when-closed">
<!-- Parse the body text containing <ul> with logic -->
<ul>
<li v-for="listItem in this.arrayOfListItemsFromBodyText" :key="listItem">
<!-- no textLink -->
<span
v-if="!doesCopyContainTextLink(listItem)"
v-html="listItem"></span>
<!-- with textLink -->
<template
v-else
v-for="copy in splitCopyOnCMSPlaceHolder(listItem)"
:key="copy">
<span v-if="!doesCopyContainTextLink(copy)" v-html="copy"></span>
<span v-else>
<textLink
linkType="text"
:text="getRouterLinkDisplayTextFromCopy(copy)"
href="#!"
@click-event="
$emit('buttonEvent', {
eventName: 'openModal',
args: getRouterLinkRouteFromCopy(copy),
})
"
:data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)" />
</span>
</template>
</li>
</ul>
<!-- End of body text parsing -->
<div
class="package-footer fw-bold caption ms-n4 mt-4"
v-if="this.buttonFooterCopy"
v-html="this.buttonFooterCopy"></div>
</div>
<div
v-if="
this.additionalButtonData.servicePackageDiscount &&
this.additionalButtonData.Text
"
class="special-save-box">
<span v-html="this.additionalButtonData.Text"></span>
</div>
</div>
</div>
</baseInputButton>
</template>
<script>
import baseInputButton from "@/digital-components/base-input-button/base-input-button";
import textLink from "@/ux-components/text-link/text-link";
import inputButtonWrapperMixin from "@/mixins/input-button-wrapper-mixin";
import {
getRouterLinkDisplayTextFromCopy,
getRouterLinkRouteFromCopy,
splitCopyOnCMSPlaceHolder,
doesCopyContainTextLink,
} from "@/helpers/cms-content-helper";
import experimentMixin from "@/mixins/experiment-mixin";
import { experimentSettings } from "@/constants/experiments";
import store from "@/store";
export default {
name: "servicePackageRadio",
mixins: [inputButtonWrapperMixin],
props: {
isInsuranceSelected: Boolean,
},
components: {
baseInputButton,
textLink,
},
computed: {
arrayOfListItemsFromBodyText() {
return this.getArrayOfListItemsFromRawCmsCopy(this.buttonBodyCopy);
},
shouldDisplayStrikeThroughPrice() {
const displayPrice = this.buttonAuxillaryCopy.substring(
this.buttonAuxillaryCopy.indexOf("$")
);
return displayPrice != this.additionalButtonData.strikeThroughPrice;
},
getDisplayPrice() {
return this.buttonAuxillaryCopy.split(".")[0];
},
},
methods: {
getRouterLinkDisplayTextFromCopy,
getRouterLinkRouteFromCopy,
splitCopyOnCMSPlaceHolder,
doesCopyContainTextLink,
stripUlTagFromCopy(copy) {
const regex = /(?:<ul(?:.*?)>)|(?:<\/ul>)/g;
return copy.replace(regex, "");
},
getArrayOfListItemsFromRawCmsCopy(copy) {
const withoutUlTags = this.stripUlTagFromCopy(copy);
return withoutUlTags
.split(/(?:<li(?:.*?)>)|(?:<\/li>)/g)
.filter((lineItem) => lineItem);
},
},
};
</script>
<style lang="scss">
.package-main {
.package-wrapper {
margin: 1rem 0;
&:first-child {
margin: 1rem 0 0 0;
}
&:last-child {
margin: 1rem 0 0 0;
}
@include media-breakpoint-up(md) {
margin: 1rem 0.5rem 0 0.5rem;
display: flex;
flex-direction: column;
&:first-child {
margin: 1rem 0.5rem 0 0;
}
&:last-child {
margin: 1rem 0 0 0.5rem;
}
}
label {
display: block;
@include media-breakpoint-up(md) {
display: flex;
height: 100%;
}
}
input[type="radio"] {
opacity: 0;
position: absolute;
left: -9999px;
+ .package-label.pricing-by-day-pkg-lbl {
@include media-breakpoint-up(md) {
padding-bottom: 0.75rem;
}
}
+ .package-label.pricing-by-day-pkg-lbl.adjust-top {
/* Copying a component for an experiment will cause duplication of css classes.
This can cause problems if you want change the value of something only for the experiment
version of the component. So added a more specific selector for the parts I want to change
If this experiment wins, move this to package-label ::before/::after below
*/
&:before {
top: 0.9375rem;
}
&:after {
top: 1.875rem;
}
@include media-breakpoint-up(lg) {
&:before {
top: 0.5rem;
}
&:after {
top: 1.4375rem;
}
p {
span {
align-self: center;
}
}
}
}
+ .package-label.pricing-by-day-pkg-lbl-ins {
&:before {
top: 0.3125rem;
}
&:after {
top: 1.25rem;
}
}
+ .package-label.pricing-by-day-pkg-lbl {
&:before {
top: 0.9375rem;
@include media-breakpoint-up(lg) {
top: 0.3125rem;
}
}
&:after {
top: 1.25rem;
}
@include media-breakpoint-up(md) {
padding-bottom: 0.75rem;
}
}
+ .package-label {
display: flex;
align-items: flex-start;
position: relative;
cursor: pointer;
width: 100%;
padding: 0.75rem;
border: 1px solid $gray-300;
box-shadow:
0px 4px 8px -4px rgba(0, 0, 0, 0.15),
0px 4px 24px -8px rgba(0, 0, 0, 0.2);
border-radius: 0.5rem;
overflow: hidden;
min-height: 52px;
max-height: 126px;
@include media-breakpoint-up(md) {
max-height: 500px;
padding-bottom: 3rem;
}
transition: max-height 0.25s ease-in;
&.has-subheader {
min-height: 72px;
}
&:before {
content: "";
position: relative;
margin-right: 0.5rem;
border-radius: 50%;
border: 1px solid $gray-500;
width: 16px;
height: 16px;
min-width: 16px;
}
&:after {
content: "";
position: absolute;
left: 15px;
border-radius: 50%;
width: 10px;
height: 10px;
min-width: 10px;
}
}
&:hover {
+ .package-label {
&:before {
border: 1px solid #8e9292;
box-shadow:
0px 0px 0px 4px #9fcee6,
0px 1px 4px rgba(0, 0, 0, 0.2);
}
}
}
&:checked {
+ .package-label {
.package-specs {
max-height: 1000px;
}
}
+ .package-label {
.package-specs {
.hide-when-closed {
display: block;
}
}
}
+ .package-label {
background-color: $blue-100;
border: 1px solid $blue;
max-height: 500px;
.special-save-box {
background-color: $green-200;
}
}
+ .package-label {
&:before {
box-shadow: 0px 0px 0px 1px $blue;
}
}
+ .package-label {
&:after {
background: $blue;
}
}
}
&:focus {
+ .package-label {
&:before {
border: 2px solid $blue;
}
}
}
}
.package-footer {
color: $red;
font-weight: 600;
}
.package-specs {
display: flex;
flex-direction: column;
width: 100%;
transition: all 0.5s ease;
@include media-breakpoint-up(md) {
max-height: 500px;
}
span.pricing-by-day {
color: #4d5151;
display: block;
white-space: nowrap;
}
.row {
align-items: center;
}
p {
font-weight: 600;
display: flex;
justify-content: space-between;
align-items: center;
white-space: nowrap;
span {
&.pricing-info-pricing-by-day {
text-align: end;
color: $green;
font-size: 1rem;
line-height: 1;
span.strikethrough-price {
text-decoration: line-through;
font-size: 0.75rem;
font-weight: 400;
color: $gray-550;
padding-right: 8px;
}
}
}
&.sub-label {
color: $green;
text-transform: uppercase;
font-size: 0.75rem;
}
}
span {
&.service-package-discount-pricing-by-day {
color: $green;
text-align: end;
font-weight: 600;
font-size: 0.875rem;
display: flex;
justify-content: flex-end;
align-items: center;
align-self: flex-start;
line-height: 1;
div.strikethrough-discount-price {
display: inline;
text-decoration: line-through;
margin-right: 0.5rem;
font-weight: 400;
font-size: 0.75rem;
line-height: 20px;
color: $gray-550;
@include media-breakpoint-up(md) {
margin-right: 0.5rem;
font-size: 0.75rem;
}
}
div.discount-price {
color: $green;
display: inline;
font-size: 1rem;
}
}
.caption {
font-size: 0.625rem;
}
}
ul {
margin: 1rem 0 0 -5px;
padding: 0;
li {
font-size: 0.875rem;
line-height: 1.714;
color: $gray-550;
a {
line-height: 1.714;
padding: 0;
}
}
}
@keyframes slideaway {
from {
display: block;
}
to {
transform: translateY(40px);
opacity: 0;
}
}
.hide-when-closed {
display: none;
@include media-breakpoint-up(md) {
display: flex;
flex-direction: column;
}
}
}
.discount-text {
height: 2rem;
display: flex;
border-top-right-radius: 0.5rem;
border-top-left-radius: 0.5rem;
background-color: $green;
align-items: center;
justify-content: center;
width: 100%;
color: white;
text-transform: uppercase;
font-size: 0.875rem;
font-weight: 600;
letter-spacing: 0.75px;
}
.special-save-box {
background-color: $green-100;
display: flex;
flex-direction: row;
margin: auto;
margin-left: -1.25rem;
padding: 0.5rem 1rem;
border-radius: 0.25rem;
margin-top: 0.5rem;
span {
color: $green;
font-size: 0.875rem;
font-weight: 600;
}
}
}
}
</style>