diff --git a/@kiva/kv-components/utils/loanCardMixin.js b/@kiva/kv-components/utils/loanCardMixin.js
new file mode 100644
index 00000000..4c1c4698
--- /dev/null
+++ b/@kiva/kv-components/utils/loanCardMixin.js
@@ -0,0 +1,252 @@
+import { mdiMapMarker } from '@mdi/js';
+
+const LSE_LOAN_KEY = 'N/A';
+const ECO_FRIENDLY_KEY = 'ECO-FRIENDLY';
+const SUSTAINABLE_AG_KEY = 'SUSTAINABLE AG';
+const SINGLE_PARENT_KEY = 'SINGLE PARENT';
+const REFUGEE_KEY = 'REFUGEES/DISPLACED';
+
+export default {
+ props: {
+ loanId: {
+ type: Number,
+ default: undefined,
+ },
+ loan: {
+ type: Object,
+ default: null,
+ },
+ customLoanDetails: {
+ type: Boolean,
+ default: false,
+ },
+ showTags: {
+ type: Boolean,
+ default: false,
+ },
+ categoryPageName: {
+ type: String,
+ default: '',
+ },
+ enableFiveDollarsNotes: {
+ type: Boolean,
+ default: false,
+ },
+ isAdding: {
+ type: Boolean,
+ default: false,
+ },
+ isVisitor: {
+ type: Boolean,
+ default: true,
+ },
+ basketItems: {
+ type: Array,
+ default: () => ([]),
+ },
+ isBookmarked: {
+ type: Boolean,
+ default: false,
+ },
+ kvTrackFunction: {
+ type: Function,
+ required: true,
+ },
+ photoPath: {
+ type: String,
+ required: true,
+ },
+ showViewLoan: {
+ type: Boolean,
+ default: false,
+ },
+ externalLinks: {
+ type: Boolean,
+ default: false,
+ },
+ route: {
+ type: Object,
+ default: undefined,
+ },
+ userBalance: {
+ type: String,
+ default: undefined,
+ },
+ getCookie: {
+ type: Function,
+ default: undefined,
+ },
+ setCookie: {
+ type: Function,
+ default: undefined,
+ },
+ fiveDollarsSelected: {
+ type: Boolean,
+ default: false,
+ },
+ customCallouts: {
+ type: Array,
+ default: () => ([]),
+ },
+ },
+ data() {
+ return {
+ mdiMapMarker,
+ };
+ },
+ computed: {
+ tag() {
+ return this.externalLinks ? 'a' : 'router-link';
+ },
+ readMorePath() {
+ return this.customLoanDetails ? '' : `/lend/${this.loanId}`;
+ },
+ isLoading() {
+ return !this.loanId || !this.loan;
+ },
+ borrowerName() {
+ return this.loan?.name || '';
+ },
+ countryName() {
+ return this.loan?.geocode?.country?.name || '';
+ },
+ city() {
+ return this.loan?.geocode?.city || '';
+ },
+ state() {
+ return this.loan?.geocode?.state || '';
+ },
+ distributionModel() {
+ return this.loan?.distributionModel || '';
+ },
+ imageHash() {
+ return this.loan?.image?.hash ?? '';
+ },
+ hasProgressData() {
+ // Local resolver values for the progress bar load client-side
+ return typeof this.loan?.unreservedAmount !== 'undefined'
+ && typeof this.loan?.fundraisingPercent !== 'undefined';
+ },
+ allDataLoaded() {
+ return !this.isLoading && this.hasProgressData;
+ },
+ fundraisingPercent() {
+ return this.loan?.fundraisingPercent ?? 0;
+ },
+ unreservedAmount() {
+ const stringAmount = this.loan?.unreservedAmount ?? '0';
+ // convert stringAmount to a number
+ return Number(stringAmount);
+ },
+ formattedLocation() {
+ if (this.distributionModel === 'direct') {
+ const formattedString = `${this.city}, ${this.state}, ${this.countryName}`;
+ return formattedString;
+ }
+ if (this.countryName === 'Puerto Rico') {
+ const formattedString = `${this.city}, PR`;
+ return formattedString;
+ }
+ return this.countryName;
+ },
+ loanUse() {
+ return this.loan?.use ?? '';
+ },
+ loanStatus() {
+ return this.loan?.status ?? '';
+ },
+ loanAmount() {
+ return this.loan?.loanAmount ?? '0';
+ },
+ loanBorrowerCount() {
+ return this.loan?.borrowerCount ?? 0;
+ },
+ loanCallouts() {
+ const callouts = [];
+ const activityName = this.loan?.activity?.name ?? '';
+ const sectorName = this.loan?.sector?.name ?? '';
+ const tags = this.loan?.tags?.filter((tag) => tag.charAt(0) === '#')
+ .map((tag) => tag.substring(1)) ?? [];
+ const themes = this.loan?.themes ?? [];
+ const categories = {
+ ecoFriendly: !!tags // eslint-disable-next-line max-len
+ .filter((t) => t.toUpperCase() === ECO_FRIENDLY_KEY || t.toUpperCase() === SUSTAINABLE_AG_KEY).length,
+ refugeesIdps: !!themes.filter((t) => t.toUpperCase() === REFUGEE_KEY).length,
+ singleParents: !!tags.filter((t) => t.toUpperCase() === SINGLE_PARENT_KEY).length,
+ };
+
+ const isLseLoan = this.loan?.partnerName?.toUpperCase().includes(LSE_LOAN_KEY);
+
+ // P1 Category
+ // Exp limited to: Eco-friendly, Refugees and IDPs, Single Parents
+ // Tag as first option for LSE loans
+ if (isLseLoan && tags.length) {
+ const position = Math.floor(Math.random() * tags.length);
+ const tag = tags[position];
+ callouts.push(tag);
+ }
+
+ if (!this.categoryPageName) {
+ if (categories.ecoFriendly // eslint-disable-next-line max-len
+ && !callouts.find((c) => c.toUpperCase() === ECO_FRIENDLY_KEY || c.toUpperCase() === SUSTAINABLE_AG_KEY)) {
+ callouts.push('Eco-friendly');
+ } else if (categories.refugeesIdps) {
+ callouts.push('Refugees and IDPs');
+ } else if (categories.singleParents
+ && !callouts.find((c) => c.toUpperCase() === SINGLE_PARENT_KEY)) {
+ callouts.push('Single Parent');
+ }
+ }
+
+ // P2 Activity
+ if (activityName && this.categoryPageName?.toUpperCase() !== activityName.toUpperCase()) {
+ callouts.push(activityName);
+ }
+
+ // P3 Sector
+ if (sectorName
+ && (activityName.toUpperCase() !== sectorName.toUpperCase())
+ && (sectorName.toUpperCase() !== this.categoryPageName?.toUpperCase())
+ && callouts.length < 2) {
+ callouts.push(sectorName);
+ }
+
+ // P4 Tag
+ if (!!tags.length && callouts.length < 2) {
+ const position = Math.floor(Math.random() * tags.length);
+ const tag = tags[position];
+ if (!callouts.filter((c) => c.toUpperCase() === tag.toUpperCase()).length) {
+ callouts.push(tag);
+ }
+ }
+
+ // P5 Theme
+ if (!!themes.length && callouts.length < 2) {
+ const position = Math.floor(Math.random() * themes.length);
+ const theme = themes[position];
+ if (!callouts.filter((c) => c.toUpperCase() === theme.toUpperCase()).length
+ && theme.toUpperCase() !== this.categoryPageName?.toUpperCase()) {
+ callouts.push(theme);
+ }
+ }
+
+ // Only show one callout for LSE loans
+ if (isLseLoan && callouts.length > 1) return [callouts.shift()];
+
+ // Add all custom callouts if available
+ callouts.push(...this.customCallouts);
+ return callouts;
+ },
+ },
+ methods: {
+ showLoanDetails(e) {
+ if (this.customLoanDetails) {
+ e.preventDefault();
+ this.$emit('show-loan-details');
+ }
+ },
+ clickReadMore(target) {
+ this.kvTrackFunction('Lending', 'click-Read more', target, this.loanId);
+ },
+ },
+};
diff --git a/@kiva/kv-components/vue/KvClassicLoanCard.vue b/@kiva/kv-components/vue/KvClassicLoanCard.vue
index e26ad5a3..014eacd4 100644
--- a/@kiva/kv-components/vue/KvClassicLoanCard.vue
+++ b/@kiva/kv-components/vue/KvClassicLoanCard.vue
@@ -220,7 +220,7 @@
diff --git a/@kiva/kv-components/vue/KvWideLoanCard.vue b/@kiva/kv-components/vue/KvWideLoanCard.vue
index 8cdf5f80..7d91348c 100644
--- a/@kiva/kv-components/vue/KvWideLoanCard.vue
+++ b/@kiva/kv-components/vue/KvWideLoanCard.vue
@@ -226,7 +226,7 @@
diff --git a/@kiva/kv-components/vue/stories/KvWideLoanCard.stories.js b/@kiva/kv-components/vue/stories/KvWideLoanCard.stories.js
index f4968ddd..772ff383 100644
--- a/@kiva/kv-components/vue/stories/KvWideLoanCard.stories.js
+++ b/@kiva/kv-components/vue/stories/KvWideLoanCard.stories.js
@@ -19,7 +19,6 @@ const story = (args) => {
:category-page-name="categoryPageName"
:enable-five-dollars-notes="enableFiveDollarsNotes"
:five-dollars-selected="fiveDollarsSelected"
- :large-card="largeCard"
:is-adding="isAdding"
:is-visitor="isVisitor"
:basket-items="basketItems"