Skip to content

Commit

Permalink
Merge pull request #5606 from kiva/badge-modal-completed-MP-839
Browse files Browse the repository at this point in the history
feat: modal content for completed badges
  • Loading branch information
christian14b authored Oct 16, 2024
2 parents c39d113 + accbc87 commit 17c0644
Show file tree
Hide file tree
Showing 5 changed files with 442 additions and 0 deletions.
129 changes: 129 additions & 0 deletions .storybook/mock-data/contentful-badge-data-mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
export default {
"metadata": {
"tags": [],
"concepts": []
},
"sys": {
"space": {
"sys": {
"type": "Link",
"linkType": "Space",
"id": "j0p9a6ql0rn7"
}
},
"id": "5qVq3IF07C8um3AiQVjLK5",
"type": "Entry",
"createdAt": "2024-10-08T20:25:25.114Z",
"updatedAt": "2024-10-15T23:11:19.111Z",
"environment": {
"sys": {
"id": "development",
"type": "Link",
"linkType": "Environment"
}
},
"revision": 4,
"contentType": {
"sys": {
"type": "Link",
"linkType": "ContentType",
"id": "challenge"
}
},
"locale": "en-US"
},
"fields": {
"key": "us-economic-equality-level-2",
"challengeName": "U.S. Economic equality (level 2)",
"badgeImage": {
"metadata": {
"tags": []
},
"sys": {
"space": {
"sys": {
"type": "Link",
"linkType": "Space",
"id": "j0p9a6ql0rn7"
}
},
"id": "62zEUpZbO7qWZPoV1z2pZU",
"type": "Asset",
"createdAt": "2024-10-08T20:25:01.320Z",
"updatedAt": "2024-10-08T20:25:01.320Z",
"environment": {
"sys": {
"id": "development",
"type": "Link",
"linkType": "Environment"
}
},
"revision": 1,
"locale": "en-US"
},
"fields": {
"title": "US Economic Equality Level 2",
"description": "",
"file": {
"url": "//images.ctfassets.net/j0p9a6ql0rn7/62zEUpZbO7qWZPoV1z2pZU/f094aa821bdf8a5f8634b28562135594/US_Economic_Equality_Level_2.svg",
"details": {
"size": 18162550,
"image": {
"width": 2382,
"height": 2382
}
},
"fileName": "US Economic Equality Level 2.svg",
"contentType": "image/svg+xml"
}
}
},
"thankYouImage": {
"metadata": {
"tags": []
},
"sys": {
"space": {
"sys": {
"type": "Link",
"linkType": "Space",
"id": "j0p9a6ql0rn7"
}
},
"id": "62zEUpZbO7qWZPoV1z2pZU",
"type": "Asset",
"createdAt": "2024-10-08T20:25:01.320Z",
"updatedAt": "2024-10-08T20:25:01.320Z",
"environment": {
"sys": {
"id": "development",
"type": "Link",
"linkType": "Environment"
}
},
"revision": 1,
"locale": "en-US"
},
"fields": {
"title": "US Economic Equality Level 2",
"description": "",
"file": {
"url": "//images.ctfassets.net/j0p9a6ql0rn7/62zEUpZbO7qWZPoV1z2pZU/f094aa821bdf8a5f8634b28562135594/US_Economic_Equality_Level_2.svg",
"details": {
"size": 18162550,
"image": {
"width": 2382,
"height": 2382
}
},
"fileName": "US Economic Equality Level 2.svg",
"contentType": "image/svg+xml"
}
}
},
"shareFact": "3 in 5 U.S. business owners brought in more income after their Kiva loan.*",
"shareFactUrl": "/",
"dateTagline": "N/A",
"shareFactFootnote": "Kiva borrowers surveyed by 60 Decibels."
}
}
50 changes: 50 additions & 0 deletions .storybook/mock-data/tiered-lending-achievement-data-mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
export default [{
"id": "us-economic-equality",
"tiers": [
{
"completedDate": "2021-01-01T00:00:00Z",
"learnMoreURL": "",
"target": 2,
"tierStatement": ""
},
{
"completedDate": "2021-01-01T00:00:00Z",
"learnMoreURL": "",
"target": 3,
"tierStatement": ""
},
{
"completedDate": "2021-01-01T00:00:00Z",
"learnMoreURL": "",
"target": 5,
"tierStatement": ""
},
{
"completedDate": "2021-01-01T00:00:00Z",
"learnMoreURL": "",
"target": 10,
"tierStatement": ""
},
{
"completedDate": "2021-04-20T00:00:00Z",
"learnMoreURL": "https://www.kiva.org/impact/systemically-marginalized-communities",
"target": 20,
"tierStatement": "70% of U.S. business owners surveyed were more confident in their business as a result of their loan.*"
},
{
"completedDate": null,
"learnMoreURL": "",
"target": 50,
"tierStatement": ""
},
{
"completedDate": null,
"learnMoreURL": "",
"target": 100,
"tierStatement": ""
},
],
"description": "description",
"totalProgressToAchievement": 0,
"status": "PARTIALLY_COMPLETE"
}]
31 changes: 31 additions & 0 deletions .storybook/stories/MyKivaBadgeCompleted.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import BadgeCompleted from '#src/components/MyKiva/BadgeCompleted.vue';
import contentfulBadge from '../mock-data/contentful-badge-data-mock';
import tieredLendingAchievement from '../mock-data/tiered-lending-achievement-data-mock';

export default {
title: 'MyKiva/BadgeCompleted',
component: BadgeCompleted,
};

const story = (args = {}) => {
const template = (_args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { BadgeCompleted },
setup() { return { args }; },
template: `
<badge-completed v-bind="args" />
`,
});
template.args = args;
return template;
};

export const Default = story({
badge: contentfulBadge,
lendingAchievement: tieredLendingAchievement[0],
lender: {
publicName: 'Christian',
public: true,
publicId: 'christian78848470'
}
});
179 changes: 179 additions & 0 deletions src/components/MyKiva/BadgeCompleted.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<template>
<div class="container">
<div class="badge-container tw-flex-col tw-mb-4">
<h2 class="tw-text-center tw-mb-2">
{{ badgeTitle }}
</h2>
<div class="tw-relative tw-z-1 tw-mb-3" :style="{ minWidth: '16rem'}">
<div
class="tw-absolute tw-h-full tw-z-docked"
>
<MyKivaBadgeStars badge-completed :style="{ minWidth: '16rem'}" class="tw-h-full" />
</div>

<img
:src="badgeImage"
class="badge tw-z-2"
:alt="badgeTitle"
>
</div>
<h2 class="tw-italic tw-font-medium tw-text-desert-rose-4 tw-mb-2 tw-text-center">
{{ funFact }}<a
:href="learnMoreLink"
v-kv-track-event="[
'portfolio',
'click',
'Already earned badge modal - Learn more',
badgeCategory,
badgeLevel
]"
class="tw-underline tw-text-desert-rose-4 hover:tw-text-desert-rose-4"
> Learn more</a>
</h2>
<h4 class="tw-text-secondary">
{{ earnedDate }}
</h4>
</div>
<KvSocialShareButton
class="share-button"
v-kv-track-event="[
'portfolio',
'click',
'Already earned badge modal - Share badge',
badgeCategory,
badgeLevel
]"
variant="primary"
modal-title="Celebrate your badge!"
:share-message="shareMessage"
:share-url="shareUrl"
:utm-campaign="utmCampaign"
:utm-content="utmContent"
>
<div class="tw-flex tw-gap-1 tw-items-center">
<KvMaterialIcon :icon="mdiExportVariant" class="tw-w-2.5 tw-h-2.5 tw-text-white" />
<span class="tw-font-medium">Share</span>
</div>
</KvSocialShareButton>
<p class="tw-text-small tw-text-center tw-text-secondary tw-mt-1.5">
{{ funFactSource }}
</p>
</div>
</template>

<script setup>
import KvSocialShareButton from '#src/components/Kv/KvSocialShareButton';
import MyKivaBadgeStars from '#src/components/MyKiva/MyKivaBadgeStars';
import KvMaterialIcon from '@kiva/kv-components/vue/KvMaterialIcon';
import confetti from 'canvas-confetti';
import {
defineProps,
computed,
toRefs,
onMounted
} from 'vue';
import { format } from 'date-fns';
import { mdiExportVariant } from '@mdi/js';
const props = defineProps({
badge: {
type: Object,
default: () => ({}),
},
lender: {
type: Object,
default: () => ({}),
},
lendingAchievement: {
type: Object,
default: () => ({}),
},
});
const { badge, lender, lendingAchievement } = toRefs(props);
const isPublic = computed(() => lender.value?.public && lender.value?.publicName);
const shareUrl = computed(() => (isPublic.value ? `/lender/${lender.value?.publicId}` : 'https://www.kiva.org'));
// eslint-disable-next-line max-len
const shareMessage = "It's not everyday you change a life! Thank you, from all of us at Kiva and the millions of lives changed around the world.";
const utmCampaign = computed(() => `social_share_portfolio_badge_${badge.value.id}`);
const utmContent = computed(() => {
if (lender.value?.public && lender.value?.publicName) return lender.value.publicName;
return 'anonymous';
});
const badgeImage = computed(() => {
return badge.value.fields?.badgeImage?.fields?.file?.url ?? '';
});
const badgeCategory = computed(() => badge.value?.challengeName ?? '');
const tiers = computed(() => lendingAchievement.value?.tiers ?? []);
const sortedTiers = computed(() => {
const defaultTiers = [...tiers.value];
return defaultTiers.sort((a, b) => b.target - a.target);
});
const currentTier = computed(() => {
return sortedTiers.value?.findLast(tier => tier.completedDate) ?? null;
});
const badgeLevel = computed(() => {
return currentTier.value?.target ?? 0;
});
const badgeTitle = computed(() => {
return badge.value?.fields?.challengeName ?? '';
});
const funFact = computed(() => {
return badge.value.fields?.shareFact ?? '';
});
const funFactSource = computed(() => {
return badge.value.fields?.shareFactFootnote ?? '';
});
const learnMoreLink = computed(() => badge.value.shareFactUrl ?? '');
const earnedDate = computed(() => `Earned ${format(new Date(currentTier.value.completedDate), 'MMMM do, yyyy')}`);
onMounted(() => {
confetti({
origin: {
y: 0.2
},
particleCount: 150,
spread: 200,
colors: ['#6AC395', '#223829', '#95D4B3'],
disableForReducedMotion: true,
});
});
</script>
<style lang="postcss" scoped>
.container {
@apply tw-mx-auto tw-bg-white tw-p-4.5 tw-rounded;
}
.badge-container {
@apply tw-flex tw-flex-col tw-justify-center tw-items-center;
}
.badge {
@apply tw-mx-auto;
width: 160px;
height: 160px;
@screen md {
width: 211px;
height: 211px;
}
}
.share-button {
@apply tw-mx-auto;
max-width: 328px;
}
</style>
Loading

0 comments on commit 17c0644

Please sign in to comment.