@kiva/kv-components 3.48.0 → 3.48.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/package.json +2 -2
- package/tests/unit/specs/components/KvClassicLoanCard.spec.js +136 -0
- package/tests/unit/specs/components/KvWideLoanCard.spec.js +136 -0
- package/utils/loanCard.js +189 -0
- package/vue/KvBorrowerImage.vue +11 -2
- package/vue/KvClassicLoanCard.vue +66 -165
- package/vue/KvWideLoanCard.vue +429 -0
- package/vue/stories/KvBorrowerImage.stories.js +6 -0
- package/vue/stories/KvClassicLoanCard.stories.js +33 -0
- package/vue/stories/KvWideLoanCard.stories.js +279 -0
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
>
|
|
182
182
|
<kv-loan-progress-group
|
|
183
183
|
id="loanProgress"
|
|
184
|
-
:money-left="unreservedAmount"
|
|
184
|
+
:money-left="`${unreservedAmount}`"
|
|
185
185
|
:progress-percent="fundraisingPercent"
|
|
186
186
|
class="tw-text-black"
|
|
187
187
|
/>
|
|
@@ -220,7 +220,8 @@
|
|
|
220
220
|
</template>
|
|
221
221
|
|
|
222
222
|
<script>
|
|
223
|
-
import {
|
|
223
|
+
import { loanCardComputedProperties, loanCardMethods } from '../utils/loanCard';
|
|
224
|
+
|
|
224
225
|
import KvLoanUse from './KvLoanUse.vue';
|
|
225
226
|
import KvBorrowerImage from './KvBorrowerImage.vue';
|
|
226
227
|
import KvLoanProgressGroup from './KvLoanProgressGroup.vue';
|
|
@@ -231,12 +232,6 @@ import KvLoanTag from './KvLoanTag.vue';
|
|
|
231
232
|
import KvMaterialIcon from './KvMaterialIcon.vue';
|
|
232
233
|
import KvLoadingPlaceholder from './KvLoadingPlaceholder.vue';
|
|
233
234
|
|
|
234
|
-
const LSE_LOAN_KEY = 'N/A';
|
|
235
|
-
const ECO_FRIENDLY_KEY = 'ECO-FRIENDLY';
|
|
236
|
-
const SUSTAINABLE_AG_KEY = 'SUSTAINABLE AG';
|
|
237
|
-
const SINGLE_PARENT_KEY = 'SINGLE PARENT';
|
|
238
|
-
const REFUGEE_KEY = 'REFUGEES/DISPLACED';
|
|
239
|
-
|
|
240
235
|
export default {
|
|
241
236
|
name: 'KvClassicLoanCard',
|
|
242
237
|
components: {
|
|
@@ -263,10 +258,6 @@ export default {
|
|
|
263
258
|
type: Boolean,
|
|
264
259
|
default: false,
|
|
265
260
|
},
|
|
266
|
-
useFullWidth: {
|
|
267
|
-
type: Boolean,
|
|
268
|
-
default: false,
|
|
269
|
-
},
|
|
270
261
|
showTags: {
|
|
271
262
|
type: Boolean,
|
|
272
263
|
default: false,
|
|
@@ -279,10 +270,6 @@ export default {
|
|
|
279
270
|
type: Boolean,
|
|
280
271
|
default: false,
|
|
281
272
|
},
|
|
282
|
-
largeCard: {
|
|
283
|
-
type: Boolean,
|
|
284
|
-
default: false,
|
|
285
|
-
},
|
|
286
273
|
isAdding: {
|
|
287
274
|
type: Boolean,
|
|
288
275
|
default: false,
|
|
@@ -335,80 +322,77 @@ export default {
|
|
|
335
322
|
type: Boolean,
|
|
336
323
|
default: false,
|
|
337
324
|
},
|
|
325
|
+
customCallouts: {
|
|
326
|
+
type: Array,
|
|
327
|
+
default: () => ([]),
|
|
328
|
+
},
|
|
329
|
+
useFullWidth: {
|
|
330
|
+
type: Boolean,
|
|
331
|
+
default: false,
|
|
332
|
+
},
|
|
333
|
+
largeCard: {
|
|
334
|
+
type: Boolean,
|
|
335
|
+
default: false,
|
|
336
|
+
},
|
|
338
337
|
},
|
|
339
|
-
|
|
338
|
+
setup(props) {
|
|
339
|
+
const {
|
|
340
|
+
allDataLoaded,
|
|
341
|
+
borrowerName,
|
|
342
|
+
city,
|
|
343
|
+
countryName,
|
|
344
|
+
distributionModel,
|
|
345
|
+
formattedLocation,
|
|
346
|
+
fundraisingPercent,
|
|
347
|
+
hasProgressData,
|
|
348
|
+
imageHash,
|
|
349
|
+
isLoading,
|
|
350
|
+
loanAmount,
|
|
351
|
+
loanBorrowerCount,
|
|
352
|
+
loanCallouts,
|
|
353
|
+
loanStatus,
|
|
354
|
+
loanUse,
|
|
355
|
+
mdiMapMarker,
|
|
356
|
+
readMorePath,
|
|
357
|
+
state,
|
|
358
|
+
tag,
|
|
359
|
+
unreservedAmount,
|
|
360
|
+
} = loanCardComputedProperties(props);
|
|
361
|
+
|
|
362
|
+
const {
|
|
363
|
+
clickReadMore,
|
|
364
|
+
showLoanDetails,
|
|
365
|
+
} = loanCardMethods(props);
|
|
366
|
+
|
|
340
367
|
return {
|
|
368
|
+
allDataLoaded,
|
|
369
|
+
borrowerName,
|
|
370
|
+
city,
|
|
371
|
+
countryName,
|
|
372
|
+
distributionModel,
|
|
373
|
+
formattedLocation,
|
|
374
|
+
fundraisingPercent,
|
|
375
|
+
hasProgressData,
|
|
376
|
+
imageHash,
|
|
377
|
+
isLoading,
|
|
378
|
+
loanAmount,
|
|
379
|
+
loanBorrowerCount,
|
|
380
|
+
loanCallouts,
|
|
381
|
+
loanStatus,
|
|
382
|
+
loanUse,
|
|
341
383
|
mdiMapMarker,
|
|
384
|
+
readMorePath,
|
|
385
|
+
state,
|
|
386
|
+
tag,
|
|
387
|
+
unreservedAmount,
|
|
388
|
+
clickReadMore,
|
|
389
|
+
showLoanDetails,
|
|
342
390
|
};
|
|
343
391
|
},
|
|
344
392
|
computed: {
|
|
345
|
-
tag() {
|
|
346
|
-
return this.externalLinks ? 'a' : 'router-link';
|
|
347
|
-
},
|
|
348
|
-
readMorePath() {
|
|
349
|
-
return this.customLoanDetails ? '' : `/lend/${this.loanId}`;
|
|
350
|
-
},
|
|
351
|
-
isLoading() {
|
|
352
|
-
return !this.loanId || !this.loan;
|
|
353
|
-
},
|
|
354
393
|
cardWidth() {
|
|
355
394
|
return this.useFullWidth ? '100%' : '374px';
|
|
356
395
|
},
|
|
357
|
-
borrowerName() {
|
|
358
|
-
return this.loan?.name || '';
|
|
359
|
-
},
|
|
360
|
-
countryName() {
|
|
361
|
-
return this.loan?.geocode?.country?.name || '';
|
|
362
|
-
},
|
|
363
|
-
city() {
|
|
364
|
-
return this.loan?.geocode?.city || '';
|
|
365
|
-
},
|
|
366
|
-
state() {
|
|
367
|
-
return this.loan?.geocode?.state || '';
|
|
368
|
-
},
|
|
369
|
-
distributionModel() {
|
|
370
|
-
return this.loan?.distributionModel || '';
|
|
371
|
-
},
|
|
372
|
-
imageHash() {
|
|
373
|
-
return this.loan?.image?.hash ?? '';
|
|
374
|
-
},
|
|
375
|
-
hasProgressData() {
|
|
376
|
-
// Local resolver values for the progress bar load client-side
|
|
377
|
-
return typeof this.loan?.unreservedAmount !== 'undefined'
|
|
378
|
-
&& typeof this.loan?.fundraisingPercent !== 'undefined';
|
|
379
|
-
},
|
|
380
|
-
allDataLoaded() {
|
|
381
|
-
return !this.isLoading && this.hasProgressData;
|
|
382
|
-
},
|
|
383
|
-
fundraisingPercent() {
|
|
384
|
-
return this.loan?.fundraisingPercent ?? 0;
|
|
385
|
-
},
|
|
386
|
-
unreservedAmount() {
|
|
387
|
-
return this.loan?.unreservedAmount ?? '0';
|
|
388
|
-
},
|
|
389
|
-
formattedLocation() {
|
|
390
|
-
if (this.distributionModel === 'direct') {
|
|
391
|
-
const formattedString = `${this.city}, ${this.state}, ${this.countryName}`;
|
|
392
|
-
return formattedString;
|
|
393
|
-
}
|
|
394
|
-
if (this.countryName === 'Puerto Rico') {
|
|
395
|
-
const formattedString = `${this.city}, PR`;
|
|
396
|
-
return formattedString;
|
|
397
|
-
}
|
|
398
|
-
return this.countryName;
|
|
399
|
-
},
|
|
400
|
-
loanUse() {
|
|
401
|
-
return this.loan?.use ?? '';
|
|
402
|
-
},
|
|
403
|
-
loanStatus() {
|
|
404
|
-
return this.loan?.status ?? '';
|
|
405
|
-
},
|
|
406
|
-
loanAmount() {
|
|
407
|
-
return this.loan?.loanAmount ?? '0';
|
|
408
|
-
},
|
|
409
|
-
loanBorrowerCount() {
|
|
410
|
-
return this.loan?.borrowerCount ?? 0;
|
|
411
|
-
},
|
|
412
396
|
imageAspectRatio() {
|
|
413
397
|
if (this.largeCard) {
|
|
414
398
|
return 5 / 8;
|
|
@@ -430,95 +414,12 @@ export default {
|
|
|
430
414
|
{ width: 335, viewSize: 375 },
|
|
431
415
|
];
|
|
432
416
|
},
|
|
433
|
-
loanCallouts() {
|
|
434
|
-
const callouts = [];
|
|
435
|
-
const activityName = this.loan?.activity?.name ?? '';
|
|
436
|
-
const sectorName = this.loan?.sector?.name ?? '';
|
|
437
|
-
const tags = this.loan?.tags?.filter((tag) => tag.charAt(0) === '#')
|
|
438
|
-
.map((tag) => tag.substring(1)) ?? [];
|
|
439
|
-
const themes = this.loan?.themes ?? [];
|
|
440
|
-
const categories = {
|
|
441
|
-
ecoFriendly: !!tags // eslint-disable-next-line max-len
|
|
442
|
-
.filter((t) => t.toUpperCase() === ECO_FRIENDLY_KEY || t.toUpperCase() === SUSTAINABLE_AG_KEY).length,
|
|
443
|
-
refugeesIdps: !!themes.filter((t) => t.toUpperCase() === REFUGEE_KEY).length,
|
|
444
|
-
singleParents: !!tags.filter((t) => t.toUpperCase() === SINGLE_PARENT_KEY).length,
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
const isLseLoan = this.loan?.partnerName?.toUpperCase().includes(LSE_LOAN_KEY);
|
|
448
|
-
|
|
449
|
-
// P1 Category
|
|
450
|
-
// Exp limited to: Eco-friendly, Refugees and IDPs, Single Parents
|
|
451
|
-
// Tag as first option for LSE loans
|
|
452
|
-
if (isLseLoan && tags.length) {
|
|
453
|
-
const position = Math.floor(Math.random() * tags.length);
|
|
454
|
-
const tag = tags[position];
|
|
455
|
-
callouts.push(tag);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
if (!this.categoryPageName) {
|
|
459
|
-
if (categories.ecoFriendly // eslint-disable-next-line max-len
|
|
460
|
-
&& !callouts.find((c) => c.toUpperCase() === ECO_FRIENDLY_KEY || c.toUpperCase() === SUSTAINABLE_AG_KEY)) {
|
|
461
|
-
callouts.push('Eco-friendly');
|
|
462
|
-
} else if (categories.refugeesIdps) {
|
|
463
|
-
callouts.push('Refugees and IDPs');
|
|
464
|
-
} else if (categories.singleParents
|
|
465
|
-
&& !callouts.find((c) => c.toUpperCase() === SINGLE_PARENT_KEY)) {
|
|
466
|
-
callouts.push('Single Parent');
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// P2 Activity
|
|
471
|
-
if (activityName && this.categoryPageName?.toUpperCase() !== activityName.toUpperCase()) {
|
|
472
|
-
callouts.push(activityName);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// P3 Sector
|
|
476
|
-
if (sectorName
|
|
477
|
-
&& (activityName.toUpperCase() !== sectorName.toUpperCase())
|
|
478
|
-
&& (sectorName.toUpperCase() !== this.categoryPageName?.toUpperCase())
|
|
479
|
-
&& callouts.length < 2) {
|
|
480
|
-
callouts.push(sectorName);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// P4 Tag
|
|
484
|
-
if (!!tags.length && callouts.length < 2) {
|
|
485
|
-
const position = Math.floor(Math.random() * tags.length);
|
|
486
|
-
const tag = tags[position];
|
|
487
|
-
if (!callouts.filter((c) => c.toUpperCase() === tag.toUpperCase()).length) {
|
|
488
|
-
callouts.push(tag);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
// P5 Theme
|
|
493
|
-
if (!!themes.length && callouts.length < 2) {
|
|
494
|
-
const position = Math.floor(Math.random() * themes.length);
|
|
495
|
-
const theme = themes[position];
|
|
496
|
-
if (!callouts.filter((c) => c.toUpperCase() === theme.toUpperCase()).length
|
|
497
|
-
&& theme.toUpperCase() !== this.categoryPageName?.toUpperCase()) {
|
|
498
|
-
callouts.push(theme);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
// Only show one callout for LSE loans
|
|
503
|
-
if (isLseLoan && callouts.length > 1) return [callouts.shift()];
|
|
504
|
-
return callouts;
|
|
505
|
-
},
|
|
506
|
-
},
|
|
507
|
-
methods: {
|
|
508
|
-
showLoanDetails(e) {
|
|
509
|
-
if (this.customLoanDetails) {
|
|
510
|
-
e.preventDefault();
|
|
511
|
-
this.$emit('show-loan-details');
|
|
512
|
-
}
|
|
513
|
-
},
|
|
514
|
-
clickReadMore(target) {
|
|
515
|
-
this.kvTrackFunction('Lending', 'click-Read more', target, this.loanId);
|
|
516
|
-
},
|
|
517
417
|
},
|
|
518
418
|
};
|
|
519
419
|
</script>
|
|
520
420
|
|
|
521
421
|
<style lang="postcss" scoped>
|
|
422
|
+
/** Shared with KvWideLoanCard */
|
|
522
423
|
.loan-card-use:hover,
|
|
523
424
|
.loan-card-use:focus {
|
|
524
425
|
@apply tw-text-primary;
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="
|
|
4
|
+
tw-flex
|
|
5
|
+
tw-flex-row
|
|
6
|
+
tw-flex-wrap
|
|
7
|
+
tw-bg-white
|
|
8
|
+
tw-rounded
|
|
9
|
+
tw-w-full
|
|
10
|
+
tw-pb-1
|
|
11
|
+
tw-p-1
|
|
12
|
+
tw-gap-1
|
|
13
|
+
tw-items-center
|
|
14
|
+
"
|
|
15
|
+
:class="{'tw-pointer-events-none' : isLoading }"
|
|
16
|
+
style="box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);"
|
|
17
|
+
>
|
|
18
|
+
<div
|
|
19
|
+
class="loan-card-active-hover tw-flex-1 tw-min-w-[275px] md:tw-min-w-[320px] md:tw-max-w-[320px]"
|
|
20
|
+
>
|
|
21
|
+
<!-- Borrower image -->
|
|
22
|
+
<kv-loading-placeholder
|
|
23
|
+
v-if="isLoading"
|
|
24
|
+
class="tw-mb-1 tw-w-full tw-rounded"
|
|
25
|
+
:style="{ height: '15rem' }"
|
|
26
|
+
/>
|
|
27
|
+
<div
|
|
28
|
+
v-else
|
|
29
|
+
class="tw-relative tw-w-full"
|
|
30
|
+
@click="showLoanDetails"
|
|
31
|
+
>
|
|
32
|
+
<component
|
|
33
|
+
:is="tag"
|
|
34
|
+
:to="readMorePath"
|
|
35
|
+
:href="readMorePath"
|
|
36
|
+
class="tw-flex"
|
|
37
|
+
aria-label="Borrower image"
|
|
38
|
+
@click="clickReadMore('Photo')"
|
|
39
|
+
>
|
|
40
|
+
<kv-borrower-image
|
|
41
|
+
class="
|
|
42
|
+
tw-relative
|
|
43
|
+
tw-w-full
|
|
44
|
+
tw-bg-black
|
|
45
|
+
tw-rounded
|
|
46
|
+
"
|
|
47
|
+
:alt="`Photo of ${borrowerName}`"
|
|
48
|
+
:aspect-ratio="imageAspectRatio"
|
|
49
|
+
:default-image="{ width: imageDefaultWidth }"
|
|
50
|
+
:hash="imageHash"
|
|
51
|
+
:images="imageSizes"
|
|
52
|
+
:photo-path="photoPath"
|
|
53
|
+
/>
|
|
54
|
+
|
|
55
|
+
<div v-if="countryName">
|
|
56
|
+
<p
|
|
57
|
+
class="
|
|
58
|
+
tw-absolute
|
|
59
|
+
tw-bottom-1
|
|
60
|
+
tw-left-1
|
|
61
|
+
tw-text-primary
|
|
62
|
+
tw-bg-white
|
|
63
|
+
tw-rounded
|
|
64
|
+
tw-p-1
|
|
65
|
+
tw-mb-0
|
|
66
|
+
tw-mr-2
|
|
67
|
+
tw-text-h4
|
|
68
|
+
tw-inline-flex
|
|
69
|
+
tw-items-center"
|
|
70
|
+
style="padding: 2px 6px; text-transform: capitalize;"
|
|
71
|
+
>
|
|
72
|
+
<kv-material-icon
|
|
73
|
+
class="tw-h-2 tw-w-2"
|
|
74
|
+
:icon="mdiMapMarker"
|
|
75
|
+
/>
|
|
76
|
+
{{ formattedLocation }}
|
|
77
|
+
</p>
|
|
78
|
+
</div>
|
|
79
|
+
</component>
|
|
80
|
+
<kv-loan-bookmark
|
|
81
|
+
v-if="!isVisitor"
|
|
82
|
+
:loan-id="loanId"
|
|
83
|
+
:is-bookmarked="isBookmarked"
|
|
84
|
+
class="tw-absolute tw-right-1"
|
|
85
|
+
style="top: -6px;"
|
|
86
|
+
data-testid="loan-card-bookmark"
|
|
87
|
+
@toggle-bookmark="$emit('toggle-bookmark')"
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<div
|
|
93
|
+
class="tw-flex tw-flex-col tw-flex-1 tw-px-1"
|
|
94
|
+
>
|
|
95
|
+
<h3 class="tw-hidden md:tw-inline-block">
|
|
96
|
+
{{ borrowerName }}
|
|
97
|
+
</h3>
|
|
98
|
+
<!-- Loan tag -->
|
|
99
|
+
<component
|
|
100
|
+
:is="tag"
|
|
101
|
+
:to="readMorePath"
|
|
102
|
+
:href="readMorePath"
|
|
103
|
+
class="tw-flex hover:tw-no-underline focus:tw-no-underline"
|
|
104
|
+
aria-label="Loan tag"
|
|
105
|
+
@click="clickReadMore('Tag')"
|
|
106
|
+
>
|
|
107
|
+
<kv-loan-tag
|
|
108
|
+
v-if="showTags && !isLoading"
|
|
109
|
+
:loan="loan"
|
|
110
|
+
:kv-track-function="kvTrackFunction"
|
|
111
|
+
/>
|
|
112
|
+
</component>
|
|
113
|
+
|
|
114
|
+
<component
|
|
115
|
+
:is="tag"
|
|
116
|
+
:to="readMorePath"
|
|
117
|
+
:href="readMorePath"
|
|
118
|
+
class="loan-card-use tw-text-primary"
|
|
119
|
+
aria-label="Loan use"
|
|
120
|
+
@click="clickReadMore('Use')"
|
|
121
|
+
>
|
|
122
|
+
<!-- Loan use -->
|
|
123
|
+
<div class="tw-pt-1">
|
|
124
|
+
<div
|
|
125
|
+
v-if="isLoading"
|
|
126
|
+
class="tw-w-full"
|
|
127
|
+
style="height: 5.5rem;"
|
|
128
|
+
>
|
|
129
|
+
<div
|
|
130
|
+
v-for="(_n, i) in [...Array(4)]"
|
|
131
|
+
:key="i"
|
|
132
|
+
class="tw-h-2 tw-mb-1"
|
|
133
|
+
>
|
|
134
|
+
<kv-loading-placeholder />
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
<div v-else>
|
|
138
|
+
<kv-loan-use
|
|
139
|
+
:use="loanUse"
|
|
140
|
+
:loan-amount="loanAmount"
|
|
141
|
+
:status="loanStatus"
|
|
142
|
+
:borrower-count="loanBorrowerCount"
|
|
143
|
+
:name="borrowerName"
|
|
144
|
+
:distribution-model="distributionModel"
|
|
145
|
+
/>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</component>
|
|
149
|
+
<!-- Loan call outs -->
|
|
150
|
+
<kv-loading-placeholder
|
|
151
|
+
v-if="isLoading || typeof loanCallouts === 'undefined'"
|
|
152
|
+
class="tw-mt-1.5 tw-mb-1"
|
|
153
|
+
:style="{ width: '60%', height: '1.75rem', 'border-radius': '500rem' }"
|
|
154
|
+
/>
|
|
155
|
+
|
|
156
|
+
<kv-loan-callouts
|
|
157
|
+
v-else
|
|
158
|
+
:callouts="loanCallouts"
|
|
159
|
+
class="loan-callouts tw-my-1.5"
|
|
160
|
+
/>
|
|
161
|
+
|
|
162
|
+
<div class="tw-flex tw-flex-row tw-justify-between tw-gap-1 md:tw-gap-3 ">
|
|
163
|
+
<!-- Fundraising -->
|
|
164
|
+
<div
|
|
165
|
+
v-if="!hasProgressData"
|
|
166
|
+
class="tw-w-full tw-pt-1 tw-pr-1"
|
|
167
|
+
>
|
|
168
|
+
<kv-loading-placeholder
|
|
169
|
+
class="tw-mb-0.5"
|
|
170
|
+
:style="{ width: '70%', height: '1.3rem' }"
|
|
171
|
+
/>
|
|
172
|
+
|
|
173
|
+
<kv-loading-placeholder
|
|
174
|
+
class="tw-rounded"
|
|
175
|
+
:style="{ width: '70%', height: '0.5rem' }"
|
|
176
|
+
/>
|
|
177
|
+
</div>
|
|
178
|
+
<component
|
|
179
|
+
:is="tag"
|
|
180
|
+
v-if="unreservedAmount > 0"
|
|
181
|
+
:to="readMorePath"
|
|
182
|
+
:href="readMorePath"
|
|
183
|
+
class="loan-card-progress tw-mt-1 tw-flex-grow"
|
|
184
|
+
aria-label="Loan progress"
|
|
185
|
+
@click="clickReadMore('Progress')"
|
|
186
|
+
>
|
|
187
|
+
<kv-loan-progress-group
|
|
188
|
+
id="loanProgress"
|
|
189
|
+
:money-left="`${unreservedAmount}`"
|
|
190
|
+
:progress-percent="fundraisingPercent"
|
|
191
|
+
class="tw-text-black"
|
|
192
|
+
/>
|
|
193
|
+
</component>
|
|
194
|
+
|
|
195
|
+
<!-- CTA Button -->
|
|
196
|
+
<kv-loading-placeholder
|
|
197
|
+
v-if="!allDataLoaded"
|
|
198
|
+
class="tw-rounded tw-self-start"
|
|
199
|
+
:style="{ width: '9rem', height: '3rem' }"
|
|
200
|
+
/>
|
|
201
|
+
|
|
202
|
+
<kv-lend-cta
|
|
203
|
+
v-else
|
|
204
|
+
:loan="loan"
|
|
205
|
+
:basket-items="basketItems"
|
|
206
|
+
:is-loading="isLoading"
|
|
207
|
+
:is-adding="isAdding"
|
|
208
|
+
:enable-five-dollars-notes="enableFiveDollarsNotes"
|
|
209
|
+
:five-dollars-selected="fiveDollarsSelected"
|
|
210
|
+
:kv-track-function="kvTrackFunction"
|
|
211
|
+
:show-view-loan="showViewLoan"
|
|
212
|
+
:custom-loan-details="customLoanDetails"
|
|
213
|
+
:external-links="externalLinks"
|
|
214
|
+
:route="route"
|
|
215
|
+
:user-balance="userBalance"
|
|
216
|
+
:get-cookie="getCookie"
|
|
217
|
+
:set-cookie="setCookie"
|
|
218
|
+
class="tw-mt-auto tw-self-end"
|
|
219
|
+
:class="{'tw-flex-grow' : unreservedAmount === 0, 'tw-flex-shrink-0' : unreservedAmount > 0}"
|
|
220
|
+
@add-to-basket="$emit('add-to-basket', $event)"
|
|
221
|
+
@show-loan-details="clickReadMore('ViewLoan')"
|
|
222
|
+
/>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</template>
|
|
227
|
+
|
|
228
|
+
<script>
|
|
229
|
+
import { loanCardComputedProperties, loanCardMethods } from '../utils/loanCard';
|
|
230
|
+
import KvLoanUse from './KvLoanUse.vue';
|
|
231
|
+
import KvBorrowerImage from './KvBorrowerImage.vue';
|
|
232
|
+
import KvLoanProgressGroup from './KvLoanProgressGroup.vue';
|
|
233
|
+
import KvLoanCallouts from './KvLoanCallouts.vue';
|
|
234
|
+
import KvLendCta from './KvLendCta.vue';
|
|
235
|
+
import KvLoanBookmark from './KvLoanBookmark.vue';
|
|
236
|
+
import KvLoanTag from './KvLoanTag.vue';
|
|
237
|
+
import KvMaterialIcon from './KvMaterialIcon.vue';
|
|
238
|
+
import KvLoadingPlaceholder from './KvLoadingPlaceholder.vue';
|
|
239
|
+
|
|
240
|
+
export default {
|
|
241
|
+
name: 'KvWideLoanCard',
|
|
242
|
+
components: {
|
|
243
|
+
KvBorrowerImage,
|
|
244
|
+
KvLoadingPlaceholder,
|
|
245
|
+
KvLoanUse,
|
|
246
|
+
KvLoanProgressGroup,
|
|
247
|
+
KvMaterialIcon,
|
|
248
|
+
KvLendCta,
|
|
249
|
+
KvLoanTag,
|
|
250
|
+
KvLoanCallouts,
|
|
251
|
+
KvLoanBookmark,
|
|
252
|
+
},
|
|
253
|
+
props: {
|
|
254
|
+
loanId: {
|
|
255
|
+
type: Number,
|
|
256
|
+
default: undefined,
|
|
257
|
+
},
|
|
258
|
+
loan: {
|
|
259
|
+
type: Object,
|
|
260
|
+
default: null,
|
|
261
|
+
},
|
|
262
|
+
customLoanDetails: {
|
|
263
|
+
type: Boolean,
|
|
264
|
+
default: false,
|
|
265
|
+
},
|
|
266
|
+
showTags: {
|
|
267
|
+
type: Boolean,
|
|
268
|
+
default: false,
|
|
269
|
+
},
|
|
270
|
+
categoryPageName: {
|
|
271
|
+
type: String,
|
|
272
|
+
default: '',
|
|
273
|
+
},
|
|
274
|
+
enableFiveDollarsNotes: {
|
|
275
|
+
type: Boolean,
|
|
276
|
+
default: false,
|
|
277
|
+
},
|
|
278
|
+
isAdding: {
|
|
279
|
+
type: Boolean,
|
|
280
|
+
default: false,
|
|
281
|
+
},
|
|
282
|
+
isVisitor: {
|
|
283
|
+
type: Boolean,
|
|
284
|
+
default: true,
|
|
285
|
+
},
|
|
286
|
+
basketItems: {
|
|
287
|
+
type: Array,
|
|
288
|
+
default: () => ([]),
|
|
289
|
+
},
|
|
290
|
+
isBookmarked: {
|
|
291
|
+
type: Boolean,
|
|
292
|
+
default: false,
|
|
293
|
+
},
|
|
294
|
+
kvTrackFunction: {
|
|
295
|
+
type: Function,
|
|
296
|
+
required: true,
|
|
297
|
+
},
|
|
298
|
+
photoPath: {
|
|
299
|
+
type: String,
|
|
300
|
+
required: true,
|
|
301
|
+
},
|
|
302
|
+
showViewLoan: {
|
|
303
|
+
type: Boolean,
|
|
304
|
+
default: false,
|
|
305
|
+
},
|
|
306
|
+
externalLinks: {
|
|
307
|
+
type: Boolean,
|
|
308
|
+
default: false,
|
|
309
|
+
},
|
|
310
|
+
route: {
|
|
311
|
+
type: Object,
|
|
312
|
+
default: undefined,
|
|
313
|
+
},
|
|
314
|
+
userBalance: {
|
|
315
|
+
type: String,
|
|
316
|
+
default: undefined,
|
|
317
|
+
},
|
|
318
|
+
getCookie: {
|
|
319
|
+
type: Function,
|
|
320
|
+
default: undefined,
|
|
321
|
+
},
|
|
322
|
+
setCookie: {
|
|
323
|
+
type: Function,
|
|
324
|
+
default: undefined,
|
|
325
|
+
},
|
|
326
|
+
fiveDollarsSelected: {
|
|
327
|
+
type: Boolean,
|
|
328
|
+
default: false,
|
|
329
|
+
},
|
|
330
|
+
customCallouts: {
|
|
331
|
+
type: Array,
|
|
332
|
+
default: () => ([]),
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
setup(props) {
|
|
336
|
+
const {
|
|
337
|
+
allDataLoaded,
|
|
338
|
+
borrowerName,
|
|
339
|
+
city,
|
|
340
|
+
countryName,
|
|
341
|
+
distributionModel,
|
|
342
|
+
formattedLocation,
|
|
343
|
+
fundraisingPercent,
|
|
344
|
+
hasProgressData,
|
|
345
|
+
imageHash,
|
|
346
|
+
isLoading,
|
|
347
|
+
loanAmount,
|
|
348
|
+
loanBorrowerCount,
|
|
349
|
+
loanCallouts,
|
|
350
|
+
loanStatus,
|
|
351
|
+
loanUse,
|
|
352
|
+
mdiMapMarker,
|
|
353
|
+
readMorePath,
|
|
354
|
+
state,
|
|
355
|
+
tag,
|
|
356
|
+
unreservedAmount,
|
|
357
|
+
} = loanCardComputedProperties(props);
|
|
358
|
+
|
|
359
|
+
const {
|
|
360
|
+
clickReadMore,
|
|
361
|
+
showLoanDetails,
|
|
362
|
+
} = loanCardMethods(props);
|
|
363
|
+
|
|
364
|
+
return {
|
|
365
|
+
allDataLoaded,
|
|
366
|
+
borrowerName,
|
|
367
|
+
city,
|
|
368
|
+
countryName,
|
|
369
|
+
distributionModel,
|
|
370
|
+
formattedLocation,
|
|
371
|
+
fundraisingPercent,
|
|
372
|
+
hasProgressData,
|
|
373
|
+
imageHash,
|
|
374
|
+
isLoading,
|
|
375
|
+
loanAmount,
|
|
376
|
+
loanBorrowerCount,
|
|
377
|
+
loanCallouts,
|
|
378
|
+
loanStatus,
|
|
379
|
+
loanUse,
|
|
380
|
+
mdiMapMarker,
|
|
381
|
+
readMorePath,
|
|
382
|
+
state,
|
|
383
|
+
tag,
|
|
384
|
+
unreservedAmount,
|
|
385
|
+
clickReadMore,
|
|
386
|
+
showLoanDetails,
|
|
387
|
+
};
|
|
388
|
+
},
|
|
389
|
+
computed: {
|
|
390
|
+
cardWidth() {
|
|
391
|
+
return '374px';
|
|
392
|
+
},
|
|
393
|
+
imageAspectRatio() {
|
|
394
|
+
return 1;
|
|
395
|
+
},
|
|
396
|
+
imageDefaultWidth() {
|
|
397
|
+
return 320;
|
|
398
|
+
},
|
|
399
|
+
imageSizes() {
|
|
400
|
+
return [
|
|
401
|
+
{ width: this.imageDefaultWidth, viewSize: 1024 },
|
|
402
|
+
{ width: this.imageDefaultWidth, viewSize: 768 },
|
|
403
|
+
{ width: 416, viewSize: 480 },
|
|
404
|
+
{ width: 374, viewSize: 414 },
|
|
405
|
+
{ width: 335, viewSize: 375 },
|
|
406
|
+
];
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
};
|
|
410
|
+
</script>
|
|
411
|
+
|
|
412
|
+
<style lang="postcss" scoped>
|
|
413
|
+
/** Shared with KvClassicLoanCard */
|
|
414
|
+
.loan-card-use:hover,
|
|
415
|
+
.loan-card-use:focus {
|
|
416
|
+
@apply tw-text-primary;
|
|
417
|
+
}
|
|
418
|
+
.loan-card-active-hover:hover .loan-card-use {
|
|
419
|
+
@apply tw-underline;
|
|
420
|
+
}
|
|
421
|
+
.loan-card-progress:hover,
|
|
422
|
+
.loan-card-progress:focus {
|
|
423
|
+
@apply tw-no-underline;
|
|
424
|
+
}
|
|
425
|
+
/** Unique to this loan card */
|
|
426
|
+
.loan-callouts >>> div{
|
|
427
|
+
@apply tw-flex-wrap tw-h-auto;
|
|
428
|
+
}
|
|
429
|
+
</style>
|