Skip to content

Commit

Permalink
feat: create donation banner type
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Bedon committed Dec 5, 2023
1 parent e22600e commit 672d921
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 0 deletions.
45 changes: 45 additions & 0 deletions .storybook/stories/DonationBanner.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Vue from "vue";
import DonationBanner from "@/components/WwwFrame/PromotionalBanner/Banners/Donation/DonationBanner.vue";

// import plugins
import kivaPlugins from "@/plugins";
Vue.use(kivaPlugins);

export default {
title: "WwwFrame/Banners/DonationBanner",
component: DonationBanner,
args: {
isOpen: true,
buttonAmounts: [20, 35, 50],
headline: "Donate $50, get $25 to lend.",
frequency: "monthly",
bannerImageUrl:
"//images.ctfassets.net/j0p9a6ql0rn7/46U7dagWY4pn1vaUPLYaYx/707ada55d0152f6d4b72aa74d894a22c/icon-heart.png",
},
};

export const Default = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: {
DonationBanner,
},
template: `
<div>
<donation-banner
:button-amounts="buttonAmounts"
:headline="headline"
:body="body"
:disclaimer="hasDisclaimer"
:banner-image-url="bannerImageUrl"
:frequency="frequency"
@close-banner="onCloseBanner"
/>
</div>
`,
methods: {
onCloseBanner(bannerState) {
console.log(bannerState);
// set cookies here and isOpen state here
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<!-- eslint-disable vue/no-v-html -->
<template>
<div>
<div class="tw-py-2 lg:tw-py-3 tw-bg-brand-100">
<kv-page-container>
<div
class="tw-flex tw-flex-col md:tw-flex-row tw-items-center tw-justify-center tw-relative tw-gap-0 md:tw-gap-3"

Check failure on line 7 in src/components/WwwFrame/PromotionalBanner/Banners/Donation/DonationBanner.vue

View workflow job for this annotation

GitHub Actions / build

This line has a length of 129. Maximum allowed is 120
>
<div class="tw-mb-2 lg:tw-m-0">
<div class="tw-relative" style="width: 8rem; height: 8rem;">
<kv-contentful-img
v-if="bannerImageUrl"
class="tw-absolute tw-h-full tw-w-full tw-z-1"
:contentful-src="bannerImageUrl"
alt=""
fallback-format="gif"
:height="128"
:width="128"
/>
</div>
</div>
<div class="tw-text-center md:tw-text-left">
<h3 class="tw-inline" v-html="headline"></h3>
<a
v-if="disclaimer"
v-kv-track-event="['promo', 'click-Contentful-banner', 'disclaimer-superscript', '1']"
class="tw-text-primary"
@click="scrollToSection('#disclaimers')"
>
<sup>
1
</sup>
</a>
<div
class="tw-mb-3 tw-mt-0.5 lg:tw-mb-2 tw-whitespace-pre-wrap md:tw-max-w-sm"
v-html="body"
></div>
<div
class="
tw-flex tw-flex-wrap tw-list-none tw-m-0
tw-gap-x-1 tw-gap-y-1 md:tw-gap-1.5
tw-justify-center donation-amount
"
>
<kv-button
v-for="(buttonAmount, index) in buttonAmounts"
:key="`amount-${index}`"
v-kv-track-event="[
'promo',
'click-amount-btn',
'DonationBanner',
buttonAmount,
buttonAmount
]"
variant="secondary"
class="tw-border-brand tw-text-brand"
:href="`/donate/supportus/?dfmode=${frequency}&
dfamt=${numeral(buttonAmount).format('0.00')}`"
>
Donate ${{ buttonAmount }}
</kv-button>
<kv-button
v-kv-track-event="['promo', 'click-other', 'DonationBanner', 0, 0]"
variant="secondary"
class="other-amount"
:href="`/donate/supportus??dfmode=${frequency}&dfmat=0.00`"
>
Other
</kv-button>
</div>
<button
v-kv-track-event="[
'promo',
'click-donation-banner-close',
'x',
]" class="`
tw-flex
tw-items-center
tw-justify-center
tw-absolute
tw-h-4
tw-w-4
tw-top-0
tw-right-2
tw-rounded
hover:tw-bg-tertiary
focus:tw-bg-tertiary`" @click="onCloseBanner"
>
<kv-material-icon class="tw-h-2 tw-w-2" :icon="mdiClose" />
</button>
</div>
</div>
</kv-page-container>
</div>
</div>
</template>

<script>
import { mdiClose } from '@mdi/js';
import numeral from 'numeral';
import smoothScrollMixin from '@/plugins/smooth-scroll-mixin';
import KvPageContainer from '~/@kiva/kv-components/vue/KvPageContainer';
import KvButton from '~/@kiva/kv-components/vue/KvButton';
import KvMaterialIcon from '~/@kiva/kv-components/vue/KvMaterialIcon';
import KvContentfulImg from '~/@kiva/kv-components/vue/KvContentfulImg';
export default {
name: 'DonationBanner',
components: {
KvPageContainer,
KvButton,
KvMaterialIcon,
KvContentfulImg
},
data() {
return {
numeral,
mdiClose
};
},
mixins: [smoothScrollMixin],
props: {
buttonAmounts: {
type: Array,
default: () => [20, 35, 50],
},
headline: {
type: String,
default: ''
},
body: {
type: String,
default: ''
},
bannerImageUrl: {
type: String,
default: ''
},
disclaimer: {
type: Boolean,
default: false
},
frequency: {
type: String,
default: 'once'
},
},
methods: {
onCloseBanner() {
this.$emit('close-banner');
},
scrollToSection(sectionId) {
const elementToScrollTo = document.querySelector(sectionId);
const topOfSectionToScrollTo = elementToScrollTo?.offsetTop ?? 0;
this.smoothScrollTo({ yPosition: topOfSectionToScrollTo, millisecondsToAnimate: 750 });
},
},
};
</script>
<style lang="postcss" scoped>
.donation-amount > * {
min-width: 133px;
}
.other-amount {
@screen md {
min-width: auto !important;
}
}
.donation-amount >>> span {
@apply tw-px-1;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<template>
<div>
<donation-banner
v-if="isOpen"
:button-amounts="buttonAmounts"
:headline="headline"
:body="body"
:disclaimer="hasDisclaimer"
:banner-image-url="bannerImageUrl"
:frequency="frequency"
@close-banner="onCloseBanner"
/>
</div>
</template>

<script>
import { documentToHtmlString } from '@contentful/rich-text-html-renderer';
import DonationBanner from '@/components/WwwFrame/PromotionalBanner/Banners/Donation/DonationBanner';
export default {
name: 'DonationBannerContainer',
components: {
DonationBanner
},
props: {
donationBannerContent: {
type: Object,
default: () => {}
},
},
data() {
return {
isOpen: true,
};
},
computed: {
headline() {
const donationHeadline = this.donationBannerContent?.richText || '';
const options = {
renderNode: {
paragraph: (node, next) => `${next(node.content)}`,
},
};
return documentToHtmlString(donationHeadline, options);
},
body() {
const donationBody = this.donationBannerContent?.additionalContent?.[0]?.fields?.richText || '';
return documentToHtmlString(donationBody);
},
buttonAmounts() {
return this.donationBannerContent?.dataObject?.donationAmounts || [];
},
frequency() {
return this.donationBannerContent?.dataObject?.frequency || 'once';
},
bannerImageUrl() {
return this.donationBannerContent?.bannerImage?.fields?.file?.url || '';
},
hasDisclaimer() {
const disclaimer = this.donationBannerContent?.disclaimers?.content?.[0] || '';
return disclaimer !== '';
},
},
methods: {
onCloseBanner() {
this.isOpen = false;
},
},
};
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
v-if="appealEnabled"
:appeal-banner-content="appealBannerContent.fields"
/>
<donation-banner-container
v-if="donationEnabled"
:donation-banner-content="donationBannerContent.fields"
/>
</div>
</template>

Expand All @@ -22,6 +26,7 @@ import { globalBannerDenyList, isExcludedUrl } from '@/util/urlUtils';
import AppealBannerCircularContainer
from '@/components/WwwFrame/PromotionalBanner/Banners/AppealBanner/AppealBannerCircularContainer';
import GenericPromoBanner from '@/components/WwwFrame/PromotionalBanner/Banners/GenericPromoBanner';
import DonationBannerContainer from '@/components/WwwFrame/PromotionalBanner/Banners/Donation/DonationBannerContainer';
import { documentToHtmlString } from '~/@contentful/rich-text-html-renderer';
Expand All @@ -36,6 +41,7 @@ export default {
components: {
AppealBannerCircularContainer,
GenericPromoBanner,
DonationBannerContainer,
},
props: {
hasPromoSession: {
Expand All @@ -48,7 +54,9 @@ export default {
isPromoEnabled: false,
promoBannerContent: {},
appealBannerContent: {},
donationBannerContent: {},
appealEnabled: false,
donationEnabled: false,
customAppealEnabled: false,
};
},
Expand Down Expand Up @@ -117,6 +125,10 @@ export default {
// Custom Banner
this.customAppealEnabled = true;
this.appealBannerContent = activePromoBanner;
} else if (activePromoBanner.fields.bannerType === 'Donation Banner') {
// Donation Banner
this.donationEnabled = true;
this.donationBannerContent = activePromoBanner;
} else {
// Promo Banner
// parse the contentful richText into an html string
Expand Down

0 comments on commit 672d921

Please sign in to comment.