Skip to content

Commit

Permalink
Merge pull request #3405 from kiva/Core-236
Browse files Browse the repository at this point in the history
feat: Core-236 disclaimer text parsed and rendered from contentful wi…
  • Loading branch information
Joshua Starkey authored Nov 12, 2021
2 parents 4d68f25 + 7309044 commit 1ad4674
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 7 deletions.
169 changes: 169 additions & 0 deletions src/components/WwwFrame/DisclaimersContentful.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<template>
<div class="row">
<ol id="disclaimers" class="text-left">
<li
v-for="(disclaimer, index) in fullyBuiltDisclaimerText"
:key="index"
v-html="disclaimer"
>
</li>
</ol>
</div>
</template>

<script>
import _get from 'lodash/get';
import numeral from 'numeral';
import gql from 'graphql-tag';
import { settingEnabled, settingWithinDateRange } from '@/util/settingsUtils';
import { documentToHtmlString } from '~/@contentful/rich-text-html-renderer';
const disclaimerQuery = gql`query disclaimerQuery($basketId: String) {
contentful {
entries(contentType: "uiSetting", contentKey: "ui-global-promo")
}
my {
userAccount {
id
promoBalance
}
}
shop (basketId: $basketId) {
id
basket {
id
hasFreeCredits
totals {
redemptionCodeAvailableTotal
}
}
lendingRewardOffered
}
}`;
export default {
data() {
return {
disclaimerContent: [],
lendingRewardOffered: false,
bonusBalance: 0,
hasFreeCredits: false,
};
},
inject: ['apollo', 'cookieStore'],
apollo: {
query: disclaimerQuery,
preFetch: true,
result({ data }) {
this.disclaimerContent = [];
// gather contentful content and the uiSetting key ui-global-promo
const contentfulContent = data?.contentful?.entries?.items ?? [];
const uiGlobalPromoSetting = contentfulContent.find(item => item.fields.key === 'ui-global-promo');
// exit if missing setting or fields
if (!uiGlobalPromoSetting || !uiGlobalPromoSetting.fields) {
return false;
}
// uiGlobalPromoSetting can contain an array of different banners with
// different start/end dates first determine if setting is enabled.
const isGlobalSettingEnabled = settingEnabled(
uiGlobalPromoSetting.fields,
'active',
'startDate',
'endDate'
);
// if setting is enabled determine which banner to display
if (isGlobalSettingEnabled) {
const activePromoBanner = uiGlobalPromoSetting?.fields?.content?.find(promoContent => {
return settingEnabled(
promoContent.fields,
'active',
'startDate',
'endDate'
);
});
// gather all inactive promo banners by their start and end dates
const inactivePromoBanners = uiGlobalPromoSetting?.fields?.content?.filter(promoContent => {
const hiddenUrls = promoContent?.fields?.hiddenUrls ?? [];
// check hiddenUrl for display of disclaimers
if (hiddenUrls.includes(this.$route.path)) {
return false;
}
if (promoContent.fields.active) {
return false;
}
return settingWithinDateRange(
promoContent.fields,
'startDate',
'endDate'
);
});
if (activePromoBanner) {
// check for visibility based on current route and hiddenUrls field
const hiddenUrls = _get(activePromoBanner, 'fields.hiddenUrls', []);
if (hiddenUrls.includes(this.$route.path)) {
return false;
}
// check for visibility on promo session override
const showForPromo = _get(activePromoBanner, 'fields.showForPromo', false);
if (this.hasPromoSession && !showForPromo) {
return false;
}
// set the disclaimer text if it exists in active promo banner
const activeDisclaimerText = activePromoBanner?.fields?.disclaimers ?? null;
// if there's an active promo banner with a disclaimer,
// push that disclaimer to the disclaimerContent for display
if (activeDisclaimerText) {
this.disclaimerContent.push(documentToHtmlString(activeDisclaimerText));
}
}
// go through the inactive promoBanners, if within date range and disclaimer text exists
// push that disclaimer text to disclaimerContent
if (inactivePromoBanners.length > 0) {
inactivePromoBanners.forEach(item => {
const itemDisclaimer = item?.fields?.disclaimers ?? null;
if (itemDisclaimer) {
this.disclaimerContent.push(documentToHtmlString(itemDisclaimer));
}
});
}
// data for the hasPromoCredit function
const promoBalance = numeral(data?.my?.userAccount?.promoBalance ?? 0);
const basketPromoBalance = numeral(data?.shop?.totals?.redemptionCodeAvailableTotal ?? 0);
this.bonusBalance = promoBalance + basketPromoBalance;
this.lendingRewardOffered = data.shop.lendingRewardOffered;
this.hasFreeCredits = data.shop.basket.hasFreeCredits;
}
}
},
computed: {
// constructing the final form of the disclaimer text for display
fullyBuiltDisclaimerText() {
const builtDisclaimertext = [];
this.disclaimerContent.forEach(disclaimer => {
const prependDisclaimer = disclaimer.replace('<p>', '<p>Disclaimer: ');
builtDisclaimertext.push(prependDisclaimer);
});
return builtDisclaimertext;
},
hasPromoSession() {
// check if the user has Promo Credit
// (lending reward credit, bonus credit, or free credit)
// if they have any of the above, the banners are hidden
// so we also hide the disclaimer section
if (this.lendingRewardOffered || this.bonusBalance > 0 || this.hasFreeCredits) {
return true;
}
return false;
}
}
};
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@
</div>
<div class="appeal-banner__content small-12 columns">
<h3 class="appeal-banner__title strong" v-html="headline"></h3>
<a
v-if="disclaimer"
@click="scrollToSection('#disclaimers')"
class="appeal-banner__disclaimer-indicator"
v-kv-track-event="['promo', 'click-Contentful-banner', 'disclaimer-superscript', '1']"
>
<sup>
1
</sup>
</a>
<div class="appeal-banner__body" v-html="body"></div>
<ul class="appeal-banner__amount-list">
<li v-for="(buttonAmount, index) in buttonAmounts"
Expand Down Expand Up @@ -96,6 +106,16 @@
<div class="appeal-banner__content row align-middle">
<div class="columns">
<h4 class="appeal-banner__title" v-html="headline"></h4>
<a
v-if="disclaimer"
href="#disclaimers"
class="appeal-banner__disclaimer-indicator"
v-kv-track-event="['promo', 'click-Contentful-banner', 'disclaimer-superscript', '1']"
>
<sup>
1
</sup>
</a>
</div>
<div class="shrink columns">
<kv-button
Expand All @@ -118,6 +138,7 @@
<script>
// import numeral from 'numeral';
import smoothReflow from 'vue-smooth-reflow';
import smoothScrollMixin from '@/plugins/smooth-scroll-mixin';
import KvButton from '@/components/Kv/KvButton';
import KvIcon from '@/components/Kv/KvIcon';
Expand All @@ -131,7 +152,7 @@ export default {
KvProgressCircle,
KvContentfulImg
},
mixins: [smoothReflow],
mixins: [smoothReflow, smoothScrollMixin],
props: {
targetAmount: {
type: Number,
Expand Down Expand Up @@ -161,6 +182,10 @@ export default {
type: Boolean,
default: true
},
disclaimer: {
type: Boolean,
default: false
}
},
computed: {
isLoading() {
Expand Down Expand Up @@ -193,6 +218,11 @@ export default {
onClickToggleBanner() {
this.$emit('toggle-banner', !this.isOpen);
},
scrollToSection(sectionId) {
const elementToScrollTo = document.querySelector(sectionId);
const topOfSectionToScrollTo = elementToScrollTo?.offsetTop ?? 0;
this.smoothScrollTo({ yPosition: topOfSectionToScrollTo, millisecondsToAnimate: 750 });
}
},
mounted() {
this.$smoothReflow();
Expand Down Expand Up @@ -224,7 +254,11 @@ export default {
}
&__title {
margin-bottom: rem-calc(4);
display: inline;
}
&__disclaimer-indicator {
color: $kiva-text-dark;
}
&__amount-list {
Expand Down Expand Up @@ -303,6 +337,7 @@ export default {
}
&__body {
margin-top: rem-calc(4);
margin-bottom: 1rem;
white-space: pre-wrap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
:body="body"
:image-url="imageUrl"
:is-open="isOpen"
:disclaimer="hasDisclaimer"
@toggle-banner="onToggleBanner"
@amount-selected="onAmountSelected"
/>
Expand Down Expand Up @@ -70,6 +71,9 @@ export default {
return this.appealBannerContent?.additionalContent
?.find(content => content?.fields?.name === 'Progress Meter Image')
.fields?.images?.[0]?.fields?.file?.url || '';
},
hasDisclaimer() {
return this.appealBannerContent?.disclaimer !== '';
}
},
created() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,28 @@
<div class="content" v-html="promoBannerContent.richText">
</div>
</component>
<a
v-if="hasDisclaimer"
@click="scrollToSection('#disclaimers')"
class="disclaimer-indicator"
v-kv-track-event="['promo', 'click-Contentful-banner', 'disclaimer-superscript', '1']"
>
<sup>
1
</sup>
</a>
</div>
</template>

<script>
import KvIcon from '@/components/Kv/KvIcon';
import smoothScrollMixin from '@/plugins/smooth-scroll-mixin';
export default {
components: {
KvIcon
},
mixins: [smoothScrollMixin],
props: {
iconKey: {
type: String,
Expand All @@ -34,10 +46,18 @@ export default {
kvTrackEvent: [],
link: '',
richText: '',
disclaimer: '',
};
}
},
},
methods: {
scrollToSection(sectionId) {
const elementToScrollTo = document.querySelector(sectionId);
const topOfSectionToScrollTo = elementToScrollTo?.offsetTop ?? 0;
this.smoothScrollTo({ yPosition: topOfSectionToScrollTo, millisecondsToAnimate: 750 });
}
},
computed: {
// if the promoBannerContent includes a link, render a router-link element, else render a plain div
currentWrapperComponent() {
Expand Down Expand Up @@ -67,6 +87,9 @@ export default {
},
trimmedLink() {
return this.promoBannerContent?.link?.trim() ?? '';
},
hasDisclaimer() {
return this.promoBannerContent.disclaimer !== '';
}
},
};
Expand Down Expand Up @@ -113,6 +136,15 @@ export default {
fill: inherit;
}
.disclaimer-indicator {
color: $kiva-icon-green;
&:hover,
&:active {
color: $kiva-darkgreen;
}
}
.banner-link,
.banner-wrapper {
display: flex;
Expand Down
2 changes: 1 addition & 1 deletion src/components/WwwFrame/TheBannerArea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default {
hasPromoSession() {
// Check if the user has Promo Credit
// (lending reward credit, bonus credit, or free credit)
// If the have any of the above, we hide the banner area
// If they have any of the above, we hide the banner area
if (this.lendingRewardOffered || this.bonusBalance > 0 || this.hasFreeCredits) {
return true;
}
Expand Down
5 changes: 4 additions & 1 deletion src/components/WwwFrame/TheFooter.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<footer class="www-footer" :style="cssVars">
<disclaimers />
<nav class="small-footer hide-for-large" aria-label="Footer navigation">
<div class="row collapse">
<div class="column">
Expand Down Expand Up @@ -706,12 +707,14 @@ import { getYear } from 'date-fns';
import getCacheKey from '@/util/getCacheKey';
import KvAccordionItem from '@/components/Kv/KvAccordionItem';
import KvIcon from '@/components/Kv/KvIcon';
import Disclaimers from '@/components/WwwFrame/DisclaimersContentful';
export default {
name: 'TheFooter',
components: {
KvAccordionItem,
KvIcon
KvIcon,
Disclaimers,
},
serverCacheKey: props => getCacheKey(props.theme ? `footerThemed${props.theme.themeKey}` : 'footer'),
props: {
Expand Down
Loading

0 comments on commit 1ad4674

Please sign in to comment.