Skip to content

Commit

Permalink
feat: my kiva updates section (#5584)
Browse files Browse the repository at this point in the history
* feat: journal updates added to my kiva

* feat: more my kiva updates progress

* feat: loan updates section added to my kiva page
  • Loading branch information
roger-in-kiva authored Oct 9, 2024
1 parent 7f526fe commit b24145f
Show file tree
Hide file tree
Showing 13 changed files with 618 additions and 69 deletions.
63 changes: 63 additions & 0 deletions .storybook/stories/JournalUpdateCard.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import JournalUpdateCard from '#src/components/MyKiva/JournalUpdateCard.vue';
import { mockLoansArray } from '../utils';
import apolloStoryMixin from '../mixins/apollo-story-mixin';
import cookieStoreStoryMixin from "../mixins/cookie-store-story-mixin";

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

const mockLoans = mockLoansArray(1);

const update = {
"id": 1365244,
"body": "I’m thrilled to update you on our progress! Thanks to your support, we’ve entered the next phase of our journey—choosing the perfect fabric for our new bust-friendly styles. The swatches are on their way, and we’re evaluating two amazing options:<br />\r\n<br />\r\nCotton Spandex Jersey<br />\r\nBamboo Viscose Spandex<br />\r\n<br />\r\nBoth fabrics are not only comfortable and functional, but they are also natural and better for the environment. Choosing natural fabrics like cotton and bamboo is important to us because they are biodegradable, unlike synthetic materials that contribute to long-term pollution. Additionally, natural fabrics require fewer chemicals in their production, and bamboo in particular grows rapidly without the need for pesticides, making it a more sustainable option.<br />\r\n<br />\r\nWe prioritize breathability and comfort, but also want to do our part in reducing the fashion industry’s environmental footprint. By choosing natural fabrics, we’re working toward creating sustainable, eco-friendly clothing that looks good, feels good, and is better for the planet.<br />\r\n<br />\r\nThank you once again for your belief in our mission and for your support in helping us bring these new styles to life. I’ll keep you updated on our final choice, and as always, we are grateful for your continued support!<br />\r\n<br />\r\nWarm regards,<br />\r\nKristen Allen<br />\r\nFounder, Exclusively Kristen",
"subject": "Exciting Update: Fabric Swatches Are on the Way!",
"date": "2024-09-21T11:37:31Z",
"image": null
};

const lender = {
id: 1017469,
public: true,
inviterName: 'Test User',
};

const story = (args = {}) => {
const template = (_args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { JournalUpdateCard },
mixins: [apolloStoryMixin(), cookieStoreStoryMixin()],
setup() { return { args }; },
provide: {
$kvTrackEvent: () => Promise.resolve({
fn: () => ({}),
}),
},
template: `
<div class="tw-bg-eco-green-1 tw-p-1" style="max-width: 450px;">
<journal-update-card
v-bind="args"
@read-more-clicked="onReadMoreClicked"
@share-loan-clicked="onShareLoanClicked"
/>
</div>
`,
methods: {
onReadMoreClicked(updateId) {
console.log(updateId);
},
onShareLoanClicked() {
console.log('share loan clicked');
},
},
});
template.args = args;
return template;
};

export const Default = story({ loan: mockLoans[0], update, lender });
export const Repaying = story({ loan: { ...mockLoans[0], status: 'payingBack' }, update, lender });
export const UpdateNumber = story({ loan: mockLoans[0], update, updateNumber: '2', lender });
export const NotTruncatedBody = story({ loan: { ...mockLoans[0], status: 'payingBack' }, update: { ...update, body: 'Testing not truncated body feature.' }, lender});
75 changes: 75 additions & 0 deletions .storybook/stories/JournalUpdatesCarousel.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import JournalUpdatesCarousel from '#src/components/MyKiva/JournalUpdatesCarousel.vue';
import { mockLoansArray } from '../utils';
import apolloStoryMixin from '../mixins/apollo-story-mixin';
import cookieStoreStoryMixin from "../mixins/cookie-store-story-mixin";

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

const mockLoans = mockLoansArray(1);

const updates = [
{
"id": 1366971,
"body": "Dear Kiva lenders,<br />\r\n<br />\r\nWe’re thrilled to update you on our progress and express our gratitude for your continued support! Thanks to your generous contributions, the fabric samples for our new bust-friendly styles have just arrived, and we’re excited to begin the next phase of our journey.<br />\r\n<br />\r\nOur team is meticulously reviewing each fabric to ensure it meets our high standards for durability, breathability, and overall quality. While some of the fabrics are perfect, a few have turned out to be much too thin for our needs. We’re carefully evaluating every option to ensure that the final product will be both comfortable and long-lasting.<br />\r\n<br />\r\nThank you again for believing in our mission to bring more body-inclusive, eco-friendly fashion to the world. We couldn’t do this without you, and we’ll keep you updated on the next steps!<br />\r\n<br />\r\nWarm regards,<br />\r\nKristen",
"subject": "Thank You for Your Support: Fabric Has Arrived!",
"date": "2024-09-25T15:00:09Z",
"image": {
"id": 5680766,
"url": "https://www-0.development.kiva.org/img/w200h200/bd5e2740a161233c37d0781fea0c5653.jpg"
}
},
{
"id": 1365244,
"body": "I’m thrilled to update you on our progress! Thanks to your support, we’ve entered the next phase of our journey—choosing the perfect fabric for our new bust-friendly styles. The swatches are on their way, and we’re evaluating two amazing options:<br />\r\n<br />\r\nCotton Spandex Jersey<br />\r\nBamboo Viscose Spandex<br />\r\n<br />\r\nBoth fabrics are not only comfortable and functional, but they are also natural and better for the environment. Choosing natural fabrics like cotton and bamboo is important to us because they are biodegradable, unlike synthetic materials that contribute to long-term pollution. Additionally, natural fabrics require fewer chemicals in their production, and bamboo in particular grows rapidly without the need for pesticides, making it a more sustainable option.<br />\r\n<br />\r\nWe prioritize breathability and comfort, but also want to do our part in reducing the fashion industry’s environmental footprint. By choosing natural fabrics, we’re working toward creating sustainable, eco-friendly clothing that looks good, feels good, and is better for the planet.<br />\r\n<br />\r\nThank you once again for your belief in our mission and for your support in helping us bring these new styles to life. I’ll keep you updated on our final choice, and as always, we are grateful for your continued support!<br />\r\n<br />\r\nWarm regards,<br />\r\nKristen Allen<br />\r\nFounder, Exclusively Kristen",
"subject": "Exciting Update: Fabric Swatches Are on the Way!",
"date": "2024-09-21T11:37:31Z",
"image": null
},
{
"id": 1364885,
"body": "Thank you, I am feeling so appreciative! And thanks to all lenders who have contributed in the last couple days to get us over 22% - very exciting! I am so very grateful to this community of lenders. Thank you for helping make our dream come true. We are at the final stretch with just one day to go. Please share my loan with your network and remind them it's a loan, not a donation. I plan to pay all of you back!",
"subject": "Freeling Grateful!",
"date": "2024-09-17T16:15:28Z",
"image": null
},
{
"id": 1364834,
"body": "Thanks to your amazing support, we’ve officially entered the sampling phase for our new bust-friendly designs! We’re currently selecting fabrics and colors, and we’d love to get your input. <br />\r\n<br />\r\nWhat types of fabrics do you love? Are you into bold colors, soft pastels, or neutrals? Your feedback will help us create styles that truly resonate with our supporters.<br />\r\n<br />\r\nPlease share your thoughts in the comments below—your input means the world to us as we continue this journey together! <br />\r\n<br />\r\nThank you again for believing in Exclusively Kristen! ",
"subject": " We’re in the Sampling Phase! ",
"date": "2024-09-13T16:11:15Z",
"image": null
}
];

const lender = {
id: 1017469,
public: true,
inviterName: 'Test User',
};

const story = (args = {}) => {
const template = (_args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { JournalUpdatesCarousel },
mixins: [apolloStoryMixin(), cookieStoreStoryMixin()],
setup() { return { args }; },
provide: {
$kvTrackEvent: () => Promise.resolve({
fn: () => ({}),
}),
},
template: `
<div class="tw-bg-eco-green-1 tw-p-1">
<journal-updates-carousel v-bind="args" />
</div>
`,
});
template.args = args;
return template;
};

export const Default = story({ loan: mockLoans[0], updates, lender, totalUpdates: 4 });
export const SingleUpdate = story({ loan: mockLoans[0], updates: [updates[0]], lender, totalUpdates: 1 });
24 changes: 1 addition & 23 deletions src/components/BorrowerProfile/JournalUpdates.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,12 @@
</template>

<script>
import { gql } from 'graphql-tag';
import { createIntersectionObserver } from '#src/util/observerUtils';
import KvLoadingPlaceholder from '@kiva/kv-components/vue/KvLoadingPlaceholder';
import KvButton from '@kiva/kv-components/vue/KvButton';
import updatesQuery from '#src/graphql/query/loanUpdates.graphql';
import UpdateDetails from './UpdateDetails';
const updatesQuery = gql`query updatesQuery($loanId: Int!, $limit: Int, $offset: Int) {
lend {
loan(id: $loanId) {
id
name
updates(limit: $limit, offset: $offset ) {
totalCount
values {
id
body
subject
date
image {
id
url(customSize: "h200w700")
}
}
}
}
}
}`;
export default {
name: 'JournalUpdates',
components: {
Expand Down
16 changes: 13 additions & 3 deletions src/components/BorrowerProfile/ShareButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:utm-content="utmContent"
:open-lightbox="forceLightbox"
:loan-id="loan.id"
@lightbox-closed="closeLightbox"
>
<template #modal-content>
<div class="tw-relative">
Expand Down Expand Up @@ -74,6 +75,10 @@ export default {
variant: {
type: String,
default: 'caution'
},
openLightbox: {
type: Boolean,
default: false
}
},
created() {
Expand Down Expand Up @@ -185,9 +190,14 @@ export default {
return `${this.$route.path}`;
},
forceLightbox() {
// If query param share=true return true to force lightbox open
return this.$route.query.share === 'true';
}
// If query param share=true return true to force lightbox open or opened from prop
return this.$route.query.share === 'true' || this.openLightbox;
},
},
methods: {
closeLightbox() {
this.$emit('lightbox-closed');

Check warning on line 199 in src/components/BorrowerProfile/ShareButton.vue

View workflow job for this annotation

GitHub Actions / build

The "lightbox-closed" event has been triggered but not declared on `emits` option
},
},
};
</script>
59 changes: 38 additions & 21 deletions src/components/Iwd/ActivityAvatar.vue
Original file line number Diff line number Diff line change
@@ -1,38 +1,51 @@
<template>
<div class="tw-w-4 tw-h-4" v-if="!isDefaultProfilePic(imageFilename) && !isAnonymousUser && imageFilename">
<img
:src="lenderImageUrl"
alt="Image of lender"
class="tw-rounded-full tw-inline-block tw-w-4 tw-h-4 data-hj-suppress"
>
</div>
<div
v-else-if="!isAnonymousUser && isDefaultProfilePic(imageFilename) || !imageFilename"
class="tw-rounded-full tw-inline-flex tw-align-center tw-justify-center tw-w-4 tw-h-4"
:class="randomizedUserAvatarClass"
>
<!-- First Letter of lender name -->
<span class="tw-self-center">
{{ lenderNameFirstLetter }}
</span>
</div>
<KvLoadingPlaceholder
v-if="isLoading"
class="tw-w-4 tw-h-4 !tw-rounded-full"
/>
<div
v-else
class="tw-rounded-full tw-bg-brand tw-inline-flex tw-items-center tw-justify-center tw-w-4 tw-h-4"
class="tw-w-4 tw-h-4"
>
<!-- Kiva K logo -->
<component :is="KivaIcon" alt="Kiva Icon" />
<div class="tw-w-4 tw-h-4" v-if="!isDefaultProfilePic(imageFilename) && !isAnonymousUser && imageFilename">
<img
:src="lenderImageUrl"
alt="Image of lender"
class="tw-rounded-full tw-inline-block tw-w-4 tw-h-4 data-hj-suppress"
>
</div>
<div
v-else-if="!isAnonymousUser && isDefaultProfilePic(imageFilename) || !imageFilename"
class="tw-rounded-full tw-inline-flex tw-align-center tw-justify-center tw-w-4 tw-h-4"
:class="randomizedUserAvatarClass"
>
<!-- First Letter of lender name -->
<span class="tw-self-center">
{{ lenderNameFirstLetter }}
</span>
</div>
<div
v-else
class="tw-rounded-full tw-bg-brand tw-inline-flex tw-items-center tw-justify-center tw-w-4 tw-h-4"
>
<!-- Kiva K logo -->
<component :is="KivaIcon" alt="Kiva Icon" />
</div>
</div>
</template>

<script>
import { isLegacyPlaceholderAvatar } from '#src/util/imageUtils';
import KvLoadingPlaceholder from '@kiva/kv-components/vue/KvLoadingPlaceholder';
import { defineAsyncComponent, shallowRef } from 'vue';
const KivaIcon = shallowRef(defineAsyncComponent(() => import('#src/assets/images/helpmechoose/kiva_mark.svg')));
export default {
name: 'ActivityAvatar',
components: {
KvLoadingPlaceholder,
},
props: {
lenderImageUrl: {
type: String,
Expand All @@ -41,7 +54,11 @@ export default {
lenderName: {
type: String,
required: true
}
},
isLoading: {
type: Boolean,
default: false,
},
},
data() {
return {
Expand Down
23 changes: 20 additions & 3 deletions src/components/Kv/KvSocialShareButton.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<div class="tw-w-full">
<kv-button
v-if="variant !== 'hidden'"
class="tw-w-full"
data-testid="bp-share-cta-button"
@click="isLightboxVisible = true;"
Expand All @@ -17,7 +18,7 @@
<kv-lightbox
:visible="isLightboxVisible"
:title="modalTitle"
@lightbox-closed="isLightboxVisible = false"
@lightbox-closed="closeLightbox"
>
<slot name="modal-content"></slot>
<div
Expand Down Expand Up @@ -89,7 +90,10 @@

<script>
import {
mdiFacebook, mdiLinkedin, mdiTwitter, mdiLink
mdiFacebook,
mdiLinkedin,
mdiTwitter,
mdiLink,
} from '@mdi/js';
import socialSharingMixin from '#src/plugins/social-sharing-mixin';
import KvButton from '@kiva/kv-components/vue/KvButton';
Expand Down Expand Up @@ -117,7 +121,7 @@ export default {
variant: {
type: String,
validator: value => {
return ['primary', 'secondary', 'link', 'ghost', 'danger', 'caution'].indexOf(value) !== -1;
return ['primary', 'secondary', 'link', 'ghost', 'danger', 'caution', 'hidden'].indexOf(value) !== -1;
},
default: 'caution'
},
Expand Down Expand Up @@ -188,6 +192,19 @@ export default {
return `${base}${this.shareUrl}`;
},
},
methods: {
closeLightbox() {
this.isLightboxVisible = false;
this.$emit('lightbox-closed');

Check warning on line 198 in src/components/Kv/KvSocialShareButton.vue

View workflow job for this annotation

GitHub Actions / build

The "lightbox-closed" event has been triggered but not declared on `emits` option
},
},
watch: {
openLightbox() {
if (this.openLightbox) {
this.isLightboxVisible = true;
}
},
},
mounted() {
this.handleFacebookResponse(this.trackingCategory);
},
Expand Down
2 changes: 1 addition & 1 deletion src/components/LenderProfile/LenderSummary.vue
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export default {
this.errorMessage = '';
this.$kvTrackEvent('lender-profile', 'click', 'send-message-close-button');
},
sendMessage() {
async sendMessage() {
this.sendingMessage = true;
this.errorMessage = '';
this.apollo.mutate({
Expand Down
Loading

0 comments on commit b24145f

Please sign in to comment.