@kiva/kv-components 4.5.0 → 4.6.0

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 CHANGED
@@ -3,6 +3,36 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [4.6.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@4.5.1...@kiva/kv-components@4.6.0) (2025-01-08)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * case when unreserved amount is greater first dropdown option ([af7bac1](https://github.com/kiva/kv-ui-elements/commit/af7bac155c18e902c7fe9594d75bd74ee966564a))
12
+ * edge cases for unreserved amount and select dropdown by default ([273e13f](https://github.com/kiva/kv-ui-elements/commit/273e13fa377277bf49684ea3032da56f0e5537ff))
13
+ * new cases for unreserved amount ([2de1302](https://github.com/kiva/kv-ui-elements/commit/2de1302de738d0f2489f56721efc30d1f6ab448a))
14
+ * remove lendCtaSelectedOption modification ([10c98d0](https://github.com/kiva/kv-ui-elements/commit/10c98d04bc72eba67591e6d7dbaf6347f5026bdf))
15
+ * resolve comments and add new cases in stories ([310c152](https://github.com/kiva/kv-ui-elements/commit/310c15273d21e2610f7e7bd67c46e5c6d5bf32d5))
16
+
17
+
18
+ ### Features
19
+
20
+ * add enableHugeAmount option to preset buttons ([c07a4b1](https://github.com/kiva/kv-ui-elements/commit/c07a4b1f74532b57f15a7aef9337659462c57b2e))
21
+ * new lendCta variant with preset options as buttons plus dropdown ([1e464a7](https://github.com/kiva/kv-ui-elements/commit/1e464a7518e77657deb59cadb90f78f1dc0db287))
22
+ * new line for dropdown when huge amount flag is enabled ([c66a90e](https://github.com/kiva/kv-ui-elements/commit/c66a90e6ac0e7b4bdc15ca28f681a97eab43dfca))
23
+
24
+
25
+
26
+
27
+
28
+ ## [4.5.1](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@4.5.0...@kiva/kv-components@4.5.1) (2025-01-04)
29
+
30
+ **Note:** Version bump only for package @kiva/kv-components
31
+
32
+
33
+
34
+
35
+
6
36
  # [4.5.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@4.4.0...@kiva/kv-components@4.5.0) (2025-01-03)
7
37
 
8
38
 
@@ -54,10 +54,57 @@
54
54
  >
55
55
  <fieldset
56
56
  class="tw-w-full tw-flex"
57
+ :class="{'tw-flex-col tw-gap-1 md:tw-flex-row md:tw-justify-between': showPresetAmounts}"
57
58
  :disabled="isAdding"
58
59
  data-testid="bp-lend-cta-select-and-button"
59
60
  >
60
- <div class="amountDropdownWrapper">
61
+ <div
62
+ v-if="showPresetAmounts"
63
+ class="tw-flex tw-gap-1"
64
+ :class="{'tw-flex-wrap md:tw-flex-nowrap': enableHugeAmount}"
65
+ >
66
+ <template v-if="!isLendAmountButton">
67
+ <kv-ui-button
68
+ v-for="option in presetButtonsPrices"
69
+ :key="option"
70
+ variant="secondary"
71
+ class="tw-inline-flex tw-flex-1 preset-option tw-w-8"
72
+ :class="{'selected-option': selectedOption == option }"
73
+ data-testid="bp-lend-cta-lend-button"
74
+ type="submit"
75
+ @click="clickPresetButton(option)"
76
+ >
77
+ ${{ option }}
78
+ </kv-ui-button>
79
+ </template>
80
+ <kv-ui-select
81
+ v-if="showFilteredDropdown"
82
+ :id="`LoanAmountDropdown_${loanId}`"
83
+ v-model="selectedDropdownOption"
84
+ class="tw-min-w-12 tw-rounded filtered-dropdown"
85
+ :class="{
86
+ 'unselected-dropdown': !selectedDropdown,
87
+ 'selected-dropdown': selectedDropdown,
88
+ 'tw-w-full': enableHugeAmount
89
+ }"
90
+ aria-label="Lend amount"
91
+ @update:modelValue="trackLendAmountSelection"
92
+ @click.native.stop="clickDropdown"
93
+ >
94
+ <option
95
+ v-for="priceOption in presetDropdownPrices"
96
+ :key="priceOption"
97
+ :value="priceOption"
98
+ >
99
+ {{ priceOption !== 'Other' ? `$${priceOption}` : priceOption }}
100
+ </option>
101
+ </kv-ui-select>
102
+ </div>
103
+
104
+ <div
105
+ v-else-if="!showPresetAmounts"
106
+ class="amountDropdownWrapper"
107
+ >
61
108
  <kv-ui-select
62
109
  v-if="hideShowLendDropdown && !isLessThan25"
63
110
  :id="`LoanAmountDropdown_${loanId}`"
@@ -79,11 +126,17 @@
79
126
  </div>
80
127
 
81
128
  <!-- Lend button -->
82
- <div :class="{ 'lendButtonWrapper': hideShowLendDropdown }">
129
+ <div
130
+ :class="{
131
+ 'lendButtonWrapper': hideShowLendDropdown && !showPresetAmounts,
132
+ 'tw-hidden': isAdding && showPresetAmounts
133
+ }"
134
+ >
83
135
  <kv-ui-button
84
136
  v-if="lendButtonVisibility && !isLessThan25"
85
137
  key="lendButton"
86
138
  class="tw-inline-flex tw-flex-1"
139
+ :class="{'tw-w-full': showPresetAmounts }"
87
140
  data-testid="bp-lend-cta-lend-button"
88
141
  type="submit"
89
142
  >
@@ -95,6 +148,7 @@
95
148
  v-else-if="showLendAgain"
96
149
  key="lendAgainButton"
97
150
  class="lend-again"
151
+ :class="{'tw-w-full': showPresetAmounts }"
98
152
  data-testid="bp-lend-cta-lend-again-button"
99
153
  type="submit"
100
154
  >
@@ -218,10 +272,19 @@ export default {
218
272
  type: Function,
219
273
  default: undefined,
220
274
  },
275
+ showPresetAmounts: {
276
+ type: Boolean,
277
+ default: false,
278
+ },
279
+ kvTrackCategory: {
280
+ type: String,
281
+ default: 'Lending',
282
+ },
221
283
  },
222
284
  data() {
223
285
  return {
224
286
  mdiChevronRight,
287
+ defaultAmountOptions: [25, 50, 75],
225
288
  selectedOption: getLendCtaSelectedOption(
226
289
  this.getCookie,
227
290
  this.setCookie,
@@ -231,6 +294,7 @@ export default {
231
294
  this.userBalance,
232
295
  this.fiveDollarsSelected,
233
296
  ),
297
+ selectedDropdownOption: 'Other',
234
298
  };
235
299
  },
236
300
  computed: {
@@ -271,21 +335,49 @@ export default {
271
335
  this.isVisitor,
272
336
  );
273
337
  },
274
- ctaButtonText() {
275
- if (this.isCompleteLoanActive) {
276
- return this.primaryButtonText || 'Lend';
338
+ presetButtonsPrices() {
339
+ const prices = this.prices.slice(0, 3);
340
+
341
+ // Show only one extra option as button
342
+ if (this.prices.length === 4) {
343
+ prices.push(this.prices[3]);
277
344
  }
345
+
346
+ return prices;
347
+ },
348
+ presetDropdownPrices() {
349
+ // Hide dropdown if there is only one option
350
+ if (this.prices.length === 4) {
351
+ return [];
352
+ }
353
+
354
+ const extraDropdownPrices = this.prices.slice(this.defaultAmountOptions.length);
355
+ extraDropdownPrices.unshift('Other');
356
+
357
+ return extraDropdownPrices;
358
+ },
359
+ loanName() {
360
+ return this.loan?.name ?? '';
361
+ },
362
+ presetAmountCtaButtonText() {
363
+ return this.loan?.borrowerCount > 1 ? 'Support' : `Support ${this.loanName}`;
364
+ },
365
+ defaultCtaButtonText() {
366
+ if (this.showPresetAmounts) return this.presetAmountCtaButtonText;
367
+ return this.primaryButtonText || 'Lend';
368
+ },
369
+ ctaButtonText() {
278
370
  switch (this.state) {
279
371
  case 'loading':
280
372
  return 'Loading...';
281
373
  case 'refunded':
282
374
  case 'expired':
283
375
  default:
284
- return this.primaryButtonText || 'Lend';
376
+ return this.defaultCtaButtonText;
285
377
  }
286
378
  },
287
379
  loanInBasketButtonText() {
288
- return this.secondaryButtonText;
380
+ return this.showPresetAmounts ? 'Continue to basket' : this.secondaryButtonText;
289
381
  },
290
382
  useFormSubmit() {
291
383
  if (this.hideShowLendDropdown
@@ -347,18 +439,27 @@ export default {
347
439
  || this.isAmountBetween25And500(this.unreservedAmount));
348
440
  },
349
441
  isLendAmountButton() {
350
- return (this.lendButtonVisibility || this.state === 'lent-to')
351
- && this.isAmountLessThan25(this.unreservedAmount);
442
+ return ((this.lendButtonVisibility || this.state === 'lent-to')
443
+ && this.isAmountLessThan25(this.unreservedAmount));
352
444
  },
353
445
  isFunded() {
354
446
  return this.state === 'funded' || this.state === 'fully-reserved';
355
447
  },
356
448
  amountToLend() {
449
+ if (this.selectedDropdown) {
450
+ return this.selectedDropdownOption;
451
+ }
357
452
  return this.isLessThan25 ? this.unreservedAmount : this.selectedOption;
358
453
  },
359
454
  showLendAgain() {
360
455
  return this.isLentTo && !this.isLessThan25;
361
456
  },
457
+ selectedDropdown() {
458
+ return this.selectedDropdownOption !== 'Other';
459
+ },
460
+ showFilteredDropdown() {
461
+ return this.presetDropdownPrices.length > 1;
462
+ },
362
463
  },
363
464
  watch: {
364
465
  unreservedAmount(newValue, previousValue) {
@@ -371,14 +472,19 @@ export default {
371
472
  newValue,
372
473
  this.userBalance,
373
474
  this.fiveDollarsSelected,
475
+ this.showPresetAmounts,
374
476
  );
375
477
  }
478
+
479
+ if (this.showPresetAmounts) {
480
+ this.selectedOption = 'Other';
481
+ }
376
482
  },
377
483
  },
378
484
  methods: {
379
485
  async addToBasket() {
380
486
  this.kvTrackFunction(
381
- 'Lending',
487
+ this.kvTrackCategory,
382
488
  'Add to basket',
383
489
  this.showLendAgain ? 'Lend again' : 'lend-button-click',
384
490
  this.loanId,
@@ -396,8 +502,12 @@ export default {
396
502
  return unreservedAmount < 500 && unreservedAmount >= 25;
397
503
  },
398
504
  trackLendAmountSelection(selectedDollarAmount) {
505
+ if (this.showPresetAmounts) {
506
+ this.selectedOption = null;
507
+ }
508
+
399
509
  this.kvTrackFunction(
400
- 'Lending',
510
+ this.kvTrackCategory,
401
511
  'Modify lend amount',
402
512
  selectedDollarAmount,
403
513
  this.loanId,
@@ -405,7 +515,9 @@ export default {
405
515
  );
406
516
  },
407
517
  clickDropdown() {
408
- this.kvTrackFunction('Lending', 'click-Modify loan amount', 'open dialog', this.loanId, this.loanId);
518
+ this.kvTrackFunction(
519
+ this.kvTrackCategory, 'click-Modify loan amount', 'open dialog', this.loanId, this.loanId,
520
+ );
409
521
  },
410
522
  clickSecondaryButton(event) {
411
523
  if (this.secondaryButtonHandler) {
@@ -418,9 +530,15 @@ export default {
418
530
  this.handleCheckout();
419
531
  }
420
532
  },
533
+ clickPresetButton(selectedDollarAmount) {
534
+ this.kvTrackFunction(
535
+ this.kvTrackCategory, 'Modify lend amount', selectedDollarAmount, this.loanId, this.loanId,
536
+ );
537
+ this.selectedOption = selectedDollarAmount;
538
+ },
421
539
  handleCheckout() {
422
540
  this.kvTrackFunction(
423
- 'Lending',
541
+ this.kvTrackCategory,
424
542
  'click-Continue-to-checkout',
425
543
  'Continue to checkout',
426
544
  this.loanId,
@@ -448,4 +566,24 @@ export default {
448
566
  .lendButtonWrapper >>> span:first-child {
449
567
  border-radius: 0 14px 14px 0;
450
568
  }
569
+
570
+ .filtered-dropdown >>> select {
571
+ @apply tw-rounded tw-border-2 tw-font-medium tw-cursor-pointer;
572
+ }
573
+
574
+ .unselected-dropdown >>> select {
575
+ @apply tw-border-gray-400;
576
+ }
577
+
578
+ .selected-dropdown >>> select {
579
+ @apply tw-border-eco-green-4;
580
+ }
581
+
582
+ .preset-option >>> span.tw-w-full:first-child {
583
+ @apply tw-border-2 tw-border-gray-400;
584
+ }
585
+
586
+ .selected-option >>> span.tw-w-full:first-child {
587
+ @apply tw-border-eco-green-4;
588
+ }
451
589
  </style>
@@ -164,3 +164,169 @@ export const ViewLoanFunded = story({
164
164
  kvTrackFunction,
165
165
  showViewLoan: true,
166
166
  });
167
+
168
+ export const WithPresetOptions = story({
169
+ isLoading: false,
170
+ loan: {
171
+ id: 1,
172
+ name: 'John',
173
+ unreservedAmount: '150.00',
174
+ borrowerCount: 1,
175
+ },
176
+ kvTrackFunction,
177
+ showPresetAmounts: true,
178
+ });
179
+
180
+ export const WithPresetOptionsGroup = story({
181
+ isLoading: false,
182
+ loan: {
183
+ id: 1,
184
+ unreservedAmount: '150.00',
185
+ borrowerCount: 2,
186
+ },
187
+ kvTrackFunction,
188
+ showPresetAmounts: true,
189
+ });
190
+
191
+ export const WithPresetOptionsEqualThanLastAmount = story({
192
+ isLoading: false,
193
+ loan: {
194
+ id: 1,
195
+ unreservedAmount: '75.00',
196
+ borrowerCount: 2,
197
+ },
198
+ kvTrackFunction,
199
+ showPresetAmounts: true,
200
+ });
201
+
202
+ export const WithPresetOptionsLessThanLastAmount = story({
203
+ isLoading: false,
204
+ loan: {
205
+ id: 1,
206
+ unreservedAmount: '50.00',
207
+ borrowerCount: 2,
208
+ },
209
+ kvTrackFunction,
210
+ showPresetAmounts: true,
211
+ });
212
+
213
+ export const WithPresetOptionsLessThan25 = story({
214
+ isLoading: false,
215
+ loan: {
216
+ id: 1,
217
+ unreservedAmount: '10.00',
218
+ borrowerCount: 2,
219
+ },
220
+ kvTrackFunction,
221
+ showPresetAmounts: true,
222
+ });
223
+
224
+ export const WithPresetOptionsLessThan50 = story({
225
+ isLoading: false,
226
+ loan: {
227
+ id: 1,
228
+ unreservedAmount: '40.00',
229
+ borrowerCount: 2,
230
+ },
231
+ kvTrackFunction,
232
+ showPresetAmounts: true,
233
+ });
234
+
235
+ export const WithPresetOptionsLessThan100 = story({
236
+ isLoading: false,
237
+ loan: {
238
+ id: 1,
239
+ unreservedAmount: '80.00',
240
+ borrowerCount: 2,
241
+ },
242
+ kvTrackFunction,
243
+ showPresetAmounts: true,
244
+ });
245
+
246
+ export const WithPresetOptionsLessThan200 = story({
247
+ isLoading: false,
248
+ loan: {
249
+ id: 1,
250
+ unreservedAmount: '190.00',
251
+ borrowerCount: 2,
252
+ },
253
+ kvTrackFunction,
254
+ showPresetAmounts: true,
255
+ });
256
+
257
+ export const WithPresetOptionsHugeAmount = story({
258
+ isLoading: false,
259
+ loan: {
260
+ id: 1,
261
+ unreservedAmount: '12850.00',
262
+ },
263
+ kvTrackFunction,
264
+ enableHugeAmount: true,
265
+ isVisitor: false,
266
+ showPresetAmounts: true,
267
+ });
268
+
269
+ export const WithPresetOptionsLoading = story({
270
+ isLoading: true,
271
+ kvTrackFunction,
272
+ loan: {
273
+ id: 1,
274
+ unreservedAmount: '150.00',
275
+ borrowerCount: 2,
276
+ },
277
+ showPresetAmounts: true,
278
+ });
279
+
280
+ export const WithPresetOptionsAdding = story({
281
+ isLoading: false,
282
+ isAdding: true,
283
+ kvTrackFunction,
284
+ loan: {
285
+ id: 1,
286
+ unreservedAmount: '150.00',
287
+ borrowerCount: 2,
288
+ },
289
+ showPresetAmounts: true,
290
+ });
291
+
292
+ export const WithPresetOptionsBasketed = story({
293
+ isLoading: false,
294
+ loan: { id: 1 },
295
+ basketItems: [
296
+ {
297
+ __typename: 'LoanReservation',
298
+ id: 1,
299
+ },
300
+ ],
301
+ showPresetAmounts: true,
302
+ kvTrackFunction,
303
+ });
304
+
305
+ export const WithPresetOptionsBasketedWithSecondaryAction = story({
306
+ isLoading: false,
307
+ loan: { id: 1 },
308
+ basketItems: [
309
+ {
310
+ __typename: 'LoanReservation',
311
+ id: 1,
312
+ },
313
+ ],
314
+ externalLinks: true,
315
+ kvTrackFunction,
316
+ secondaryButtonHandler,
317
+ showPresetAmounts: true,
318
+ });
319
+
320
+ export const WithPresetOptionsFunded = story({
321
+ isLoading: false,
322
+ loan: { status: 'funded' },
323
+ kvTrackFunction,
324
+ showPresetAmounts: true,
325
+ });
326
+
327
+ export const WithPresetOptionsNonActionable = story({
328
+ isLoading: false,
329
+ loan: { status: 'refunded' },
330
+ kvTrackFunction,
331
+ showPresetAmounts: true,
332
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kiva/kv-components",
3
- "version": "4.5.0",
3
+ "version": "4.6.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -64,7 +64,7 @@
64
64
  "build": "tsup utils/*.js --outDir dist/utils --format cjs,esm --clean && cp -R vue/ dist/components/ && cp -R data/ dist/data/"
65
65
  },
66
66
  "dependencies": {
67
- "@kiva/kv-tokens": "^2.16.0",
67
+ "@kiva/kv-tokens": "^2.16.1",
68
68
  "@mdi/js": "^7.4.47",
69
69
  "@vueuse/integrations": "^9.13.0",
70
70
  "aria-hidden": "^1.1.3",
@@ -98,5 +98,5 @@
98
98
  "peerDependencies": {
99
99
  "vue": ">=3.0.0"
100
100
  },
101
- "gitHead": "0facec90197844ded4496934e85b9014d4949237"
101
+ "gitHead": "4e5a4bbf728bcf6d7c29c291591cf52798230cb0"
102
102
  }
package/vue/KvLendCta.vue CHANGED
@@ -54,10 +54,57 @@
54
54
  >
55
55
  <fieldset
56
56
  class="tw-w-full tw-flex"
57
+ :class="{'tw-flex-col tw-gap-1 md:tw-flex-row md:tw-justify-between': showPresetAmounts}"
57
58
  :disabled="isAdding"
58
59
  data-testid="bp-lend-cta-select-and-button"
59
60
  >
60
- <div class="amountDropdownWrapper">
61
+ <div
62
+ v-if="showPresetAmounts"
63
+ class="tw-flex tw-gap-1"
64
+ :class="{'tw-flex-wrap md:tw-flex-nowrap': enableHugeAmount}"
65
+ >
66
+ <template v-if="!isLendAmountButton">
67
+ <kv-ui-button
68
+ v-for="option in presetButtonsPrices"
69
+ :key="option"
70
+ variant="secondary"
71
+ class="tw-inline-flex tw-flex-1 preset-option tw-w-8"
72
+ :class="{'selected-option': selectedOption == option }"
73
+ data-testid="bp-lend-cta-lend-button"
74
+ type="submit"
75
+ @click="clickPresetButton(option)"
76
+ >
77
+ ${{ option }}
78
+ </kv-ui-button>
79
+ </template>
80
+ <kv-ui-select
81
+ v-if="showFilteredDropdown"
82
+ :id="`LoanAmountDropdown_${loanId}`"
83
+ v-model="selectedDropdownOption"
84
+ class="tw-min-w-12 tw-rounded filtered-dropdown"
85
+ :class="{
86
+ 'unselected-dropdown': !selectedDropdown,
87
+ 'selected-dropdown': selectedDropdown,
88
+ 'tw-w-full': enableHugeAmount
89
+ }"
90
+ aria-label="Lend amount"
91
+ @update:modelValue="trackLendAmountSelection"
92
+ @click.native.stop="clickDropdown"
93
+ >
94
+ <option
95
+ v-for="priceOption in presetDropdownPrices"
96
+ :key="priceOption"
97
+ :value="priceOption"
98
+ >
99
+ {{ priceOption !== 'Other' ? `$${priceOption}` : priceOption }}
100
+ </option>
101
+ </kv-ui-select>
102
+ </div>
103
+
104
+ <div
105
+ v-else-if="!showPresetAmounts"
106
+ class="amountDropdownWrapper"
107
+ >
61
108
  <kv-ui-select
62
109
  v-if="hideShowLendDropdown && !isLessThan25"
63
110
  :id="`LoanAmountDropdown_${loanId}`"
@@ -79,11 +126,17 @@
79
126
  </div>
80
127
 
81
128
  <!-- Lend button -->
82
- <div :class="{ 'lendButtonWrapper': hideShowLendDropdown }">
129
+ <div
130
+ :class="{
131
+ 'lendButtonWrapper': hideShowLendDropdown && !showPresetAmounts,
132
+ 'tw-hidden': isAdding && showPresetAmounts
133
+ }"
134
+ >
83
135
  <kv-ui-button
84
136
  v-if="lendButtonVisibility && !isLessThan25"
85
137
  key="lendButton"
86
138
  class="tw-inline-flex tw-flex-1"
139
+ :class="{'tw-w-full': showPresetAmounts }"
87
140
  data-testid="bp-lend-cta-lend-button"
88
141
  type="submit"
89
142
  >
@@ -95,6 +148,7 @@
95
148
  v-else-if="showLendAgain"
96
149
  key="lendAgainButton"
97
150
  class="lend-again"
151
+ :class="{'tw-w-full': showPresetAmounts }"
98
152
  data-testid="bp-lend-cta-lend-again-button"
99
153
  type="submit"
100
154
  >
@@ -218,10 +272,19 @@ export default {
218
272
  type: Function,
219
273
  default: undefined,
220
274
  },
275
+ showPresetAmounts: {
276
+ type: Boolean,
277
+ default: false,
278
+ },
279
+ kvTrackCategory: {
280
+ type: String,
281
+ default: 'Lending',
282
+ },
221
283
  },
222
284
  data() {
223
285
  return {
224
286
  mdiChevronRight,
287
+ defaultAmountOptions: [25, 50, 75],
225
288
  selectedOption: getLendCtaSelectedOption(
226
289
  this.getCookie,
227
290
  this.setCookie,
@@ -231,6 +294,7 @@ export default {
231
294
  this.userBalance,
232
295
  this.fiveDollarsSelected,
233
296
  ),
297
+ selectedDropdownOption: 'Other',
234
298
  };
235
299
  },
236
300
  computed: {
@@ -271,21 +335,49 @@ export default {
271
335
  this.isVisitor,
272
336
  );
273
337
  },
274
- ctaButtonText() {
275
- if (this.isCompleteLoanActive) {
276
- return this.primaryButtonText || 'Lend';
338
+ presetButtonsPrices() {
339
+ const prices = this.prices.slice(0, 3);
340
+
341
+ // Show only one extra option as button
342
+ if (this.prices.length === 4) {
343
+ prices.push(this.prices[3]);
277
344
  }
345
+
346
+ return prices;
347
+ },
348
+ presetDropdownPrices() {
349
+ // Hide dropdown if there is only one option
350
+ if (this.prices.length === 4) {
351
+ return [];
352
+ }
353
+
354
+ const extraDropdownPrices = this.prices.slice(this.defaultAmountOptions.length);
355
+ extraDropdownPrices.unshift('Other');
356
+
357
+ return extraDropdownPrices;
358
+ },
359
+ loanName() {
360
+ return this.loan?.name ?? '';
361
+ },
362
+ presetAmountCtaButtonText() {
363
+ return this.loan?.borrowerCount > 1 ? 'Support' : `Support ${this.loanName}`;
364
+ },
365
+ defaultCtaButtonText() {
366
+ if (this.showPresetAmounts) return this.presetAmountCtaButtonText;
367
+ return this.primaryButtonText || 'Lend';
368
+ },
369
+ ctaButtonText() {
278
370
  switch (this.state) {
279
371
  case 'loading':
280
372
  return 'Loading...';
281
373
  case 'refunded':
282
374
  case 'expired':
283
375
  default:
284
- return this.primaryButtonText || 'Lend';
376
+ return this.defaultCtaButtonText;
285
377
  }
286
378
  },
287
379
  loanInBasketButtonText() {
288
- return this.secondaryButtonText;
380
+ return this.showPresetAmounts ? 'Continue to basket' : this.secondaryButtonText;
289
381
  },
290
382
  useFormSubmit() {
291
383
  if (this.hideShowLendDropdown
@@ -347,18 +439,27 @@ export default {
347
439
  || this.isAmountBetween25And500(this.unreservedAmount));
348
440
  },
349
441
  isLendAmountButton() {
350
- return (this.lendButtonVisibility || this.state === 'lent-to')
351
- && this.isAmountLessThan25(this.unreservedAmount);
442
+ return ((this.lendButtonVisibility || this.state === 'lent-to')
443
+ && this.isAmountLessThan25(this.unreservedAmount));
352
444
  },
353
445
  isFunded() {
354
446
  return this.state === 'funded' || this.state === 'fully-reserved';
355
447
  },
356
448
  amountToLend() {
449
+ if (this.selectedDropdown) {
450
+ return this.selectedDropdownOption;
451
+ }
357
452
  return this.isLessThan25 ? this.unreservedAmount : this.selectedOption;
358
453
  },
359
454
  showLendAgain() {
360
455
  return this.isLentTo && !this.isLessThan25;
361
456
  },
457
+ selectedDropdown() {
458
+ return this.selectedDropdownOption !== 'Other';
459
+ },
460
+ showFilteredDropdown() {
461
+ return this.presetDropdownPrices.length > 1;
462
+ },
362
463
  },
363
464
  watch: {
364
465
  unreservedAmount(newValue, previousValue) {
@@ -371,14 +472,19 @@ export default {
371
472
  newValue,
372
473
  this.userBalance,
373
474
  this.fiveDollarsSelected,
475
+ this.showPresetAmounts,
374
476
  );
375
477
  }
478
+
479
+ if (this.showPresetAmounts) {
480
+ this.selectedOption = 'Other';
481
+ }
376
482
  },
377
483
  },
378
484
  methods: {
379
485
  async addToBasket() {
380
486
  this.kvTrackFunction(
381
- 'Lending',
487
+ this.kvTrackCategory,
382
488
  'Add to basket',
383
489
  this.showLendAgain ? 'Lend again' : 'lend-button-click',
384
490
  this.loanId,
@@ -396,8 +502,12 @@ export default {
396
502
  return unreservedAmount < 500 && unreservedAmount >= 25;
397
503
  },
398
504
  trackLendAmountSelection(selectedDollarAmount) {
505
+ if (this.showPresetAmounts) {
506
+ this.selectedOption = null;
507
+ }
508
+
399
509
  this.kvTrackFunction(
400
- 'Lending',
510
+ this.kvTrackCategory,
401
511
  'Modify lend amount',
402
512
  selectedDollarAmount,
403
513
  this.loanId,
@@ -405,7 +515,9 @@ export default {
405
515
  );
406
516
  },
407
517
  clickDropdown() {
408
- this.kvTrackFunction('Lending', 'click-Modify loan amount', 'open dialog', this.loanId, this.loanId);
518
+ this.kvTrackFunction(
519
+ this.kvTrackCategory, 'click-Modify loan amount', 'open dialog', this.loanId, this.loanId,
520
+ );
409
521
  },
410
522
  clickSecondaryButton(event) {
411
523
  if (this.secondaryButtonHandler) {
@@ -418,9 +530,15 @@ export default {
418
530
  this.handleCheckout();
419
531
  }
420
532
  },
533
+ clickPresetButton(selectedDollarAmount) {
534
+ this.kvTrackFunction(
535
+ this.kvTrackCategory, 'Modify lend amount', selectedDollarAmount, this.loanId, this.loanId,
536
+ );
537
+ this.selectedOption = selectedDollarAmount;
538
+ },
421
539
  handleCheckout() {
422
540
  this.kvTrackFunction(
423
- 'Lending',
541
+ this.kvTrackCategory,
424
542
  'click-Continue-to-checkout',
425
543
  'Continue to checkout',
426
544
  this.loanId,
@@ -448,4 +566,24 @@ export default {
448
566
  .lendButtonWrapper >>> span:first-child {
449
567
  border-radius: 0 14px 14px 0;
450
568
  }
569
+
570
+ .filtered-dropdown >>> select {
571
+ @apply tw-rounded tw-border-2 tw-font-medium tw-cursor-pointer;
572
+ }
573
+
574
+ .unselected-dropdown >>> select {
575
+ @apply tw-border-gray-400;
576
+ }
577
+
578
+ .selected-dropdown >>> select {
579
+ @apply tw-border-eco-green-4;
580
+ }
581
+
582
+ .preset-option >>> span.tw-w-full:first-child {
583
+ @apply tw-border-2 tw-border-gray-400;
584
+ }
585
+
586
+ .selected-option >>> span.tw-w-full:first-child {
587
+ @apply tw-border-eco-green-4;
588
+ }
451
589
  </style>
@@ -164,3 +164,169 @@ export const ViewLoanFunded = story({
164
164
  kvTrackFunction,
165
165
  showViewLoan: true,
166
166
  });
167
+
168
+ export const WithPresetOptions = story({
169
+ isLoading: false,
170
+ loan: {
171
+ id: 1,
172
+ name: 'John',
173
+ unreservedAmount: '150.00',
174
+ borrowerCount: 1,
175
+ },
176
+ kvTrackFunction,
177
+ showPresetAmounts: true,
178
+ });
179
+
180
+ export const WithPresetOptionsGroup = story({
181
+ isLoading: false,
182
+ loan: {
183
+ id: 1,
184
+ unreservedAmount: '150.00',
185
+ borrowerCount: 2,
186
+ },
187
+ kvTrackFunction,
188
+ showPresetAmounts: true,
189
+ });
190
+
191
+ export const WithPresetOptionsEqualThanLastAmount = story({
192
+ isLoading: false,
193
+ loan: {
194
+ id: 1,
195
+ unreservedAmount: '75.00',
196
+ borrowerCount: 2,
197
+ },
198
+ kvTrackFunction,
199
+ showPresetAmounts: true,
200
+ });
201
+
202
+ export const WithPresetOptionsLessThanLastAmount = story({
203
+ isLoading: false,
204
+ loan: {
205
+ id: 1,
206
+ unreservedAmount: '50.00',
207
+ borrowerCount: 2,
208
+ },
209
+ kvTrackFunction,
210
+ showPresetAmounts: true,
211
+ });
212
+
213
+ export const WithPresetOptionsLessThan25 = story({
214
+ isLoading: false,
215
+ loan: {
216
+ id: 1,
217
+ unreservedAmount: '10.00',
218
+ borrowerCount: 2,
219
+ },
220
+ kvTrackFunction,
221
+ showPresetAmounts: true,
222
+ });
223
+
224
+ export const WithPresetOptionsLessThan50 = story({
225
+ isLoading: false,
226
+ loan: {
227
+ id: 1,
228
+ unreservedAmount: '40.00',
229
+ borrowerCount: 2,
230
+ },
231
+ kvTrackFunction,
232
+ showPresetAmounts: true,
233
+ });
234
+
235
+ export const WithPresetOptionsLessThan100 = story({
236
+ isLoading: false,
237
+ loan: {
238
+ id: 1,
239
+ unreservedAmount: '80.00',
240
+ borrowerCount: 2,
241
+ },
242
+ kvTrackFunction,
243
+ showPresetAmounts: true,
244
+ });
245
+
246
+ export const WithPresetOptionsLessThan200 = story({
247
+ isLoading: false,
248
+ loan: {
249
+ id: 1,
250
+ unreservedAmount: '190.00',
251
+ borrowerCount: 2,
252
+ },
253
+ kvTrackFunction,
254
+ showPresetAmounts: true,
255
+ });
256
+
257
+ export const WithPresetOptionsHugeAmount = story({
258
+ isLoading: false,
259
+ loan: {
260
+ id: 1,
261
+ unreservedAmount: '12850.00',
262
+ },
263
+ kvTrackFunction,
264
+ enableHugeAmount: true,
265
+ isVisitor: false,
266
+ showPresetAmounts: true,
267
+ });
268
+
269
+ export const WithPresetOptionsLoading = story({
270
+ isLoading: true,
271
+ kvTrackFunction,
272
+ loan: {
273
+ id: 1,
274
+ unreservedAmount: '150.00',
275
+ borrowerCount: 2,
276
+ },
277
+ showPresetAmounts: true,
278
+ });
279
+
280
+ export const WithPresetOptionsAdding = story({
281
+ isLoading: false,
282
+ isAdding: true,
283
+ kvTrackFunction,
284
+ loan: {
285
+ id: 1,
286
+ unreservedAmount: '150.00',
287
+ borrowerCount: 2,
288
+ },
289
+ showPresetAmounts: true,
290
+ });
291
+
292
+ export const WithPresetOptionsBasketed = story({
293
+ isLoading: false,
294
+ loan: { id: 1 },
295
+ basketItems: [
296
+ {
297
+ __typename: 'LoanReservation',
298
+ id: 1,
299
+ },
300
+ ],
301
+ showPresetAmounts: true,
302
+ kvTrackFunction,
303
+ });
304
+
305
+ export const WithPresetOptionsBasketedWithSecondaryAction = story({
306
+ isLoading: false,
307
+ loan: { id: 1 },
308
+ basketItems: [
309
+ {
310
+ __typename: 'LoanReservation',
311
+ id: 1,
312
+ },
313
+ ],
314
+ externalLinks: true,
315
+ kvTrackFunction,
316
+ secondaryButtonHandler,
317
+ showPresetAmounts: true,
318
+ });
319
+
320
+ export const WithPresetOptionsFunded = story({
321
+ isLoading: false,
322
+ loan: { status: 'funded' },
323
+ kvTrackFunction,
324
+ showPresetAmounts: true,
325
+ });
326
+
327
+ export const WithPresetOptionsNonActionable = story({
328
+ isLoading: false,
329
+ loan: { status: 'refunded' },
330
+ kvTrackFunction,
331
+ showPresetAmounts: true,
332
+ });