wickes-css2 2.109.0-develop.3 → 2.109.0-gift-cards.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.
Files changed (112) hide show
  1. package/Readme.md +1 -2
  2. package/build/css/category-main.css +1 -1
  3. package/build/css/components/card-product-banner.css +1 -1
  4. package/build/css/components/checkout-payment-details-v2.css +1 -1
  5. package/build/css/homepage-main.css +1 -1
  6. package/build/css/kitchen-plp-main.css +1 -1
  7. package/build/css/main.css +1 -1
  8. package/build/css/my-account-main-v2.css +1 -1
  9. package/build/css/my-account-main.css +1 -1
  10. package/build/css/pages/checkout-new.css +1 -1
  11. package/build/css/pages/checkout.css +1 -1
  12. package/build/css/pages/page_checkout_delivery-new.css +1 -1
  13. package/build/css/pages/page_products-list-combined.css +1 -1
  14. package/build/css/pages/page_products-list.css +1 -1
  15. package/build/css/pages/page_shopping-cart-v2.css +1 -1
  16. package/build/css/pdp-main-before-combine.css +1 -1
  17. package/build/css/pdp-main-critical.css +1 -1
  18. package/build/css/pdp-main-non-critical.css +1 -1
  19. package/build/css/pdp-main.css +1 -1
  20. package/build/css/plp-main.css +1 -1
  21. package/build/css/store-locator-main.css +1 -1
  22. package/build/img/payment/checkout/giftcard.svg +28 -0
  23. package/build/img/payment/footer/giftcard.svg +28 -0
  24. package/build/js/basket.min.js +1 -1
  25. package/build/js/checkout.min.js +1 -1
  26. package/build/js/emulation.min.js +56 -178
  27. package/build/js/gift-cards.min.js +1 -1
  28. package/build/js/merged-checkout.min.js +1 -1
  29. package/build/js/mini-basket-slider.min.js +1 -1
  30. package/build/js/page/basket/mini-basket-total.js +2 -17
  31. package/build/js/page/checkout-payment-details.js +176 -79
  32. package/build/js/page/components/gift-cards.js +701 -357
  33. package/build/js/page/components/order-summary.js +0 -35
  34. package/build/js/pdp.bundle.min.js +1 -2
  35. package/build/js/toggle-password-visibility.min.js +1 -0
  36. package/package.json +3 -1
  37. package/src/components/base/button.hbs +1 -1
  38. package/src/components/card_product_banner_v2.hbs +1 -4
  39. package/src/components/card_sponsor_banner.hbs +1 -4
  40. package/src/components/checkout_order-summary-new.hbs +7 -10
  41. package/src/components/checkout_payment-new.hbs +31 -8
  42. package/src/components/click-and-collect-modal.hbs +14 -0
  43. package/src/components/date-selection.hbs +1 -1
  44. package/src/components/delivery-types.hbs +3 -11
  45. package/src/components/gift-cards.hbs +8 -15
  46. package/src/components/injected-content.hbs +1 -6
  47. package/src/components/modal.hbs +1 -1
  48. package/src/components/order-summary.hbs +2 -2
  49. package/src/components/payments.hbs +6 -5
  50. package/src/components/price-block-v2.hbs +214 -211
  51. package/src/data/data_checkout-giftcards.json +7 -0
  52. package/src/data/data_delivery-address-v2.json +5 -1
  53. package/src/data/data_payments-checkout.json +4 -0
  54. package/src/data/data_search-results_v2.json +2 -9
  55. package/src/data/data_spr_injected_content.json +0 -4
  56. package/src/data/footer_menu.json +4 -0
  57. package/src/img/payment/checkout/giftcard.svg +28 -0
  58. package/src/img/payment/footer/giftcard.svg +28 -0
  59. package/src/js/emulation/checkout-delivery-details.js +25 -28
  60. package/src/js/emulation/custom-slider-emulation.js +1 -1
  61. package/src/js/emulation/date-selection.js +24 -136
  62. package/src/js/emulation/forms.js +0 -12
  63. package/src/js/emulation/mini-basket-data.js +3 -3
  64. package/src/js/emulation/switchCalendar.js +8 -12
  65. package/src/js/page/basket/mini-basket-total.js +2 -17
  66. package/src/js/page/checkout-payment-details.js +176 -79
  67. package/src/js/page/components/gift-cards.js +701 -357
  68. package/src/js/page/components/order-summary.js +0 -35
  69. package/src/page_checkout_confirmation-gift-card.html +339 -0
  70. package/src/page_checkout_next-day-delivery-details.html +2 -2
  71. package/src/page_checkout_payment-details-v2-asm.html +1 -1
  72. package/src/page_checkout_payment-details-v2.html +1 -1
  73. package/src/page_checkout_payment-details_with-card-loader.html +1 -1
  74. package/src/page_checkout_payment-details_with-klarna-loader.html +1 -1
  75. package/src/page_checkout_payment-details_with-loader-v2.html +1 -1
  76. package/src/page_checkout_rapid-delivery-details.html +5 -7
  77. package/src/page_klarna_payment-details_with-klarna.html +1 -1
  78. package/src/page_payment-details-with-billie.html +1 -1
  79. package/src/page_payment-details-with-clearpay.html +1 -1
  80. package/src/page_payment-details-with-gift-card.html +2 -2
  81. package/src/page_payment-details_with_apple-pay.html +1 -1
  82. package/src/page_payment-details_with_google-pay.html +1 -1
  83. package/src/page_plp_v2.html +0 -1
  84. package/src/page_product-details-billie.html +2 -0
  85. package/src/page_product-details-clearpay.html +1 -0
  86. package/src/page_product-details-mfe-calculator.html +3 -9
  87. package/src/scss/common/_CTAs.scss +3 -7
  88. package/src/scss/components/_custom-slider.scss +0 -18
  89. package/src/scss/components/_date-selection-add-new-styles.scss +1 -43
  90. package/src/scss/components/_gift-cards.scss +32 -3
  91. package/src/scss/components/_order-summary.scss +12 -25
  92. package/src/scss/components/_payments-checkout.scss +2 -2
  93. package/src/scss/components/_payments-v2.scss +1 -1
  94. package/src/scss/components/_price-block-critical.scss +2 -2
  95. package/src/scss/components/_price-block.scss +4 -14
  96. package/src/scss/components/card-product-banner.scss +0 -8
  97. package/src/scss/helpers/_CTAs.scss +5 -15
  98. package/src/scss/helpers/_variables.scss +2 -0
  99. package/src/scss/pages/_checkout-confirmation-new.scss +86 -2
  100. package/src/scss/pages/page_checkout_delivery-new.scss +0 -36
  101. package/src/scss/pages/page_products-list-combined.scss +1 -8
  102. package/src/scss/pages/page_products-list.scss +1 -8
  103. package/src/scss/pages/page_shopping-cart-v2.scss +10 -34
  104. package/src/scss/pdp-main.scss +0 -1
  105. package/src/sitemap.html +6 -0
  106. package/build/js/page/components/notify-me.js +0 -99
  107. package/build/js/wickes-dc.js +0 -1
  108. package/src/components/modals/notify-me-modal.hbs +0 -76
  109. package/src/components/sponsor-top-banner.hbs +0 -10
  110. package/src/js/emulation/notify-me.js +0 -9
  111. package/src/js/page/components/notify-me.js +0 -99
  112. package/src/scss/components/_notify-me-modal.scss +0 -139
@@ -1,6 +1,6 @@
1
- import { initializeInputToggle } from '../utils/show-hide-input';
2
- import { updateOrderSummary } from './order-summary';
3
- import { hideLoader, showLoader, appendLoader } from '../utils/loader';
1
+ import {initializeInputToggle} from "../utils/show-hide-input";
2
+ import {updateOrderSummary} from './order-summary';
3
+ import {hideLoader, showLoader} from "../utils/loader";
4
4
  import {
5
5
  ADD_GIFT_CARD,
6
6
  buildHintContext,
@@ -43,85 +43,101 @@ const notificationTpl = require('../../../elements/notifications.hbs');
43
43
  var Wick = window.Wick || {};
44
44
 
45
45
  Wick.GiftCard = {
46
- ADD_GIFT_CARD,
47
- REMOVE_GIFT_CARD,
48
- PAY_WITH_GIFT_CARD,
49
- el: {
50
- $blocks: $('.giftcard'),
51
- block: '.giftcard',
52
- toggle: '#giftcard-toggle',
53
- panel: '#giftcard-inline',
54
- hint: '.giftcard-hint',
55
- closeBtn: '.giftcard-inline__close',
56
- form: '.giftcard-inline__form',
57
- number: 'input[name="giftcard-number"]',
58
- pin: 'input[name="giftcard-pin"]',
59
- note: '.giftcard-note',
60
- field: '.giftcard__field',
61
- errorText: '.giftcard__error-text',
62
- fieldError: 'giftcard-field--error',
63
- showToggle: '.toggle-show',
64
- loader: '.giftcard__container .loader-wrapper',
65
- success: '#giftcard-applied',
66
- container: '.giftcard__container',
67
- paymentForm: '.checkout-payment-details__payment-method',
68
- billieField: '.form-row__field.form-row__field-billie',
69
- klarnaField: '.form-row__field.form-row__field-klarna',
70
- clearpayField: '.form-row__field.form-row__field-clearpay',
71
- appleField: '.form-row__field.form-row__field-apple',
72
- googleField: '.form-row__field.form-row__field-google',
73
- paypalField: '.form-row__field.form-row__field-paypal',
74
- cardField: '.form-row__field.form-row__card-payment',
75
- summaryHint: '.giftcard-summary__hint',
76
- chipList: '.giftcard-chip-list',
77
- summary: '.giftcard-summary',
78
- chip: '.giftcard-chip',
79
- giftcardRow: '.giftcard-row',
80
- checkoutContainer: '.checkout-payment-details',
81
- formRow: '.form-row',
82
- iconInfo: '.icon-info-component',
83
- toggleIcon: 'svg, i',
84
- iconEye: 'fa-eye',
85
- iconEyeSlash: 'fa-eye-slash',
86
- iconSvgEyeSlash: 'eye-slash',
87
- passwordToggleEvent: 'input.passwordToggle',
88
- ariaInvalidAttr: 'aria-invalid',
89
- typeAttr: 'type',
90
- dataIconAttr: 'data-icon',
91
- svg: 'svg',
92
- expandedAttr: 'aria-expanded',
93
- giftcardBtn: '.giftcard__btn',
94
- jsGiftcardAdd: '.js-giftcard-add',
95
- giftcardChipClose: '.giftcard-chip__close',
96
- body: 'body',
97
- loaderChip: '.loader-wrapper',
98
- chipListLoader: '.giftcard-chip-list > .loader-wrapper',
99
- notification: '.giftcard-inline .notification',
100
- giftCardInline: '.giftcard-inline',
101
- notificationRoot: '.notification',
102
- inlineHeader: '.giftcard-inline__header',
103
- ctaSelector: '.btn-enter-details',
104
- btnDetails: 'button',
105
- btnText: '.btn__text',
106
- btnEnterDetails: '.btn-enter-details',
107
- checkoutPaymentFields: '.billing-address .checkout-payment-details__descr',
108
- pageLoader: '.loader-wrapper.page-loader',
109
- cardRadio: '#checkout-payment-details-card, #_checkout-payment-details-card_card',
110
- billieInfo: '.checkout-payment-details__billie',
111
- klarnaInfo: '.checkout-payment-details__klarna',
112
- billingAddress: '.billing-address',
113
- altPaymentRowsAttr:
114
- '[data-apple],[data-google],[data-paypal],[data-klarna],[data-billie],[data-clearpay],[data-existing-card]',
115
- hiddenCard: 'checkout-payment-details__card-details_hidden',
116
- cardDetails: '.checkout-payment-details__card-details',
117
- },
118
-
119
- messages: {
120
- numberMessage: 'Gift Card should consist of 16 digits',
121
- pinMessage: 'Gift Card PIN should consist of 8 digits',
122
- ctaDefaultText: 'Enter card details',
123
- ctaGiftcardText: 'Pay with Gift Card',
124
- },
46
+ ADD_GIFT_CARD,
47
+ REMOVE_GIFT_CARD,
48
+ PAY_WITH_GIFT_CARD,
49
+ el: {
50
+ $blocks: $('.giftcard'),
51
+ block: '.giftcard',
52
+ toggle: '#giftcard-toggle',
53
+ panel: '#giftcard-inline',
54
+ hint: '.giftcard-hint',
55
+ closeBtn: '.giftcard-inline__close',
56
+ form: '.giftcard-inline__form',
57
+ number: 'input[name="giftcard-number"]',
58
+ pin: 'input[name="giftcard-pin"]',
59
+ note: '.giftcard-note',
60
+ field: '.giftcard__field',
61
+ errorText: '.giftcard__error-text',
62
+ fieldError: 'giftcard-field--error',
63
+ showToggle: '.toggle-show',
64
+ loader: '.giftcard__container .loader-wrapper',
65
+ success: '#giftcard-applied',
66
+ container: '.giftcard__container',
67
+ paymentForm: '.checkout-payment-details__payment-method',
68
+ billieField: '.form-row__field.form-row__field-billie',
69
+ klarnaField: '.form-row__field.form-row__field-klarna',
70
+ clearpayField: '.form-row__field.form-row__field-clearpay',
71
+ appleField: '.form-row__field.form-row__field-apple',
72
+ googleField: '.form-row__field.form-row__field-google',
73
+ paypalField: '.form-row__field.form-row__field-paypal',
74
+ cardField: '.form-row__field.form-row__card-payment',
75
+ summaryHint: '.giftcard-summary__hint',
76
+ chipList: '.giftcard-chip-list',
77
+ summary: '.giftcard-summary',
78
+ chip: '.giftcard-chip',
79
+ giftcardRow: '.giftcard-row',
80
+ checkoutContainer: '.checkout-payment-details',
81
+ formRow: '.form-row',
82
+ iconInfo: '.icon-info-component',
83
+ toggleIcon: 'svg, i',
84
+ iconEye: 'fa-eye',
85
+ iconEyeSlash: 'fa-eye-slash',
86
+ iconSvgEyeSlash: 'eye-slash',
87
+ passwordToggleEvent: 'input.passwordToggle',
88
+ ariaInvalidAttr: 'aria-invalid',
89
+ typeAttr: 'type',
90
+ dataIconAttr: 'data-icon',
91
+ svg: 'svg',
92
+ expandedAttr: 'aria-expanded',
93
+ giftcardBtn: '.giftcard__btn',
94
+ jsGiftcardAdd: '.js-giftcard-add',
95
+ giftcardChipClose: '.giftcard-chip__close',
96
+ body: 'body',
97
+ loaderChip: '.loader-wrapper',
98
+ chipListLoader: '.giftcard-chip-list > .loader-wrapper',
99
+ notification: '.giftcard-inline .notification',
100
+ giftCardInline: '.giftcard-inline',
101
+ notificationRoot: '.notification',
102
+ inlineHeader: '.giftcard-inline__header',
103
+ ctaSelector: '.btn-enter-details',
104
+ btnDetails: 'button',
105
+ btnText: '.btn__text',
106
+ btnEnterDetails: '.btn-enter-details',
107
+ checkoutPaymentFields: '.billing-address .checkout-payment-details__descr',
108
+ pageLoader: '.loader-wrapper.page-loader',
109
+ cardRadio: '#checkout-payment-details-card, #_checkout-payment-details-card_card',
110
+ billieInfo: '.checkout-payment-details__billie',
111
+ klarnaInfo: '.checkout-payment-details__klarna',
112
+ billingAddress: '.billing-address',
113
+ altPaymentRowsAttr: '[data-apple-pay],[data-google-pay],[data-paypal],[data-klarna],[data-billie],[data-clearpay],[data-existing-card]',
114
+ hiddenCard: 'checkout-payment-details__card-details_hidden',
115
+ cardDetails: '.checkout-payment-details__card-details',
116
+ paymentMethodCheckedSel: 'input[name="payment-method"]:checked',
117
+ paymentMethodCardValue: 'card',
118
+ paypageNewCardSel: '[data-new-card]',
119
+ paypageExistingCardSel: '[data-existing-card]',
120
+ paypageIframeWrapSel: '.hop-iframe__wrapper',
121
+ cardValidationErrorRowSel: '.form-row_validation-error',
122
+ cardValidationErrorRowClass: 'form-row_validation-error',
123
+ cardValidationErrorTextSel: '.form-row__error',
124
+ paypageFormSel: '#hopPostForm',
125
+ paypageIframeSel: '#hopIframe',
126
+ paypageCardDetailsSel: '.checkout-payment-details__card-details',
127
+ wrapper: '.giftcard__wrapper',
128
+ },
129
+
130
+ messages: {
131
+ numberMessage: 'Gift Card should consist of 16 digits',
132
+ pinMessage: 'Gift Card PIN should consist of 8 digits',
133
+ ctaDefaultText: 'Enter card details',
134
+ ctaGiftcardText: 'Pay with Gift Card',
135
+ },
136
+
137
+ collapseTargets: [
138
+ '.billing-address input, .billing-address select, .billing-address textarea',
139
+ '.billing-address [data-finder], .billing-address [data-manually]',
140
+ ].join(','),
125
141
 
126
142
  maxChips: 3,
127
143
  successTimer: null,
@@ -163,8 +179,93 @@ Wick.GiftCard = {
163
179
  const hasValue = ($pinInput.val() || '').length > 0;
164
180
  $toggle.toggle(hasValue);
165
181
 
166
- $pinInput.trigger(passwordToggleEvent);
167
- },
182
+ $pinInput.trigger(passwordToggleEvent);
183
+ },
184
+
185
+ isPanelOpen($root) {
186
+ const $panel = $root.find(this.el.panel);
187
+ return $panel.length ? $panel.prop('hidden') === false : false;
188
+ },
189
+
190
+ openPaypage($container) {
191
+ const {
192
+ paypageFormSel,
193
+ paypageIframeSel,
194
+ paypageIframeWrapSel,
195
+ paypageCardDetailsSel,
196
+ hiddenCard,
197
+ } = this.el;
198
+
199
+ const $cardDetails = $container.find(paypageCardDetailsSel);
200
+ const $wrap = $container.find(paypageIframeWrapSel);
201
+
202
+ $cardDetails.removeClass(hiddenCard).show();
203
+ $wrap.show();
204
+
205
+
206
+ const $form = $container.find(paypageFormSel);
207
+
208
+ const form = $form.get(0);
209
+ if (!form) return;
210
+
211
+ const $oldIframe = $container.find(paypageIframeSel);
212
+ if ($oldIframe.length) {
213
+ const old = $oldIframe.get(0);
214
+ const newIframe = old.cloneNode(true);
215
+
216
+ newIframe.src = old.getAttribute('src') || newIframe.src || '';
217
+ old.parentNode.replaceChild(newIframe, old);
218
+
219
+ const iframeName = newIframe.getAttribute('name') || newIframe.name;
220
+ if (iframeName) form.setAttribute('target', iframeName);
221
+ }
222
+ },
223
+
224
+ getAppliedChipsCount($root) {
225
+ const { giftcardRow, chipList, chip } = this.el;
226
+ const $row = $root.closest(giftcardRow);
227
+ return $row.length ? $row.find(`${chipList} ${chip}`).length : 0;
228
+ },
229
+
230
+ collapseKeepValues($root) {
231
+ const { toggle, panel, hint, expandedAttr } = this.el;
232
+
233
+ $root.find(panel).prop('hidden', true);
234
+ $root.find(toggle).attr(expandedAttr, 'false').show();
235
+
236
+ const zeroTotal = this.summaryTotal != null ? isZeroAmount(this.summaryTotal) : false;
237
+ $root.find(hint)[zeroTotal ? 'hide' : 'show']();
238
+ },
239
+
240
+ handleCollapseTrigger(e) {
241
+ const $target = $(e.target);
242
+
243
+ const isCheckbox = $target.is('#chb-payment-details-card');
244
+ const isInBilling = $target.closest('.billing-address').length > 0;
245
+
246
+ if (!isCheckbox && !isInBilling) return;
247
+
248
+ const $container = $target.closest(this.el.checkoutContainer);
249
+ if (!$container.length) return;
250
+
251
+ const $giftcard = $container.find(this.el.block).first();
252
+ if (!$giftcard.length) return;
253
+
254
+ if (!this.isPanelOpen($giftcard)) return;
255
+
256
+ const chipsCount = this.getAppliedChipsCount($giftcard);
257
+
258
+ const { panel, toggle, expandedAttr } = this.el;
259
+
260
+ if (chipsCount > 0) {
261
+ this.updateHintVisibility($giftcard);
262
+ this.collapseGiftcardPanel($container, { hideIfHasChips: true });
263
+ $giftcard.find(panel).prop('hidden', true).hide();
264
+ $giftcard.find(toggle).attr(expandedAttr, 'false');
265
+ return;
266
+ }
267
+ this.collapseKeepValues($giftcard);
268
+ },
168
269
 
169
270
  resetForm($root) {
170
271
  const { number, pin, note } = this.el;
@@ -193,77 +294,118 @@ Wick.GiftCard = {
193
294
  this.resetPinToggle($root);
194
295
  },
195
296
 
196
- open($root) {
197
- const { toggle, panel, hint, pin, expandedAttr, passwordToggleEvent } = this.el;
198
- this.hideBanner($root);
199
- $root.show();
297
+ open($root) {
298
+ const { toggle, panel, hint, pin, expandedAttr, passwordToggleEvent } = this.el;
299
+ $root.show();
200
300
 
201
- $root.find(panel).prop('hidden', false);
202
- $root.find(toggle).attr(expandedAttr, 'true').hide();
203
- $root.find(hint).hide();
204
- $root.find(pin).trigger(passwordToggleEvent);
205
- },
301
+ $root.find(panel).prop('hidden', false).show();
302
+ $root.find(toggle).attr(expandedAttr, 'true').hide();
303
+ $root.find(hint).hide();
304
+ $root.find(pin).trigger(passwordToggleEvent);
305
+ },
206
306
 
207
- close($root) {
208
- const { toggle, panel, loader, expandedAttr } = this.el;
209
- const $toggle = $root.find(toggle);
210
- const $panel = $root.find(panel);
211
- const $loader = $root.find(loader);
307
+ close($root) {
308
+ const { toggle, panel, expandedAttr, giftcardRow, chipList, chip, hint } = this.el;
309
+ const $toggle = $root.find(toggle);
310
+ const $panel = $root.find(panel);
311
+ const $pageLoader = this.getPageLoader();
212
312
 
213
- showLoader($loader);
313
+ showLoader($pageLoader);
214
314
 
215
- setTimeout(() => {
216
- hideLoader($loader);
315
+ setTimeout(() => {
316
+ hideLoader($pageLoader);
217
317
 
218
- $panel.prop('hidden', true);
219
- $toggle.attr(expandedAttr, 'false').show().trigger('focus');
220
- this.updateHintVisibility($root);
221
- }, 1000);
222
- },
318
+ $panel.prop('hidden', true);
319
+ $toggle.attr(expandedAttr, 'false').show().trigger('focus');
223
320
 
224
- showSubmitSpinner($root) {
225
- const { panel, toggle, hint, expandedAttr } = this.el;
226
- $root.find(panel).prop('hidden', true);
227
- $root.find(toggle).attr(expandedAttr, 'false').show().trigger('focus');
228
- $root.find(hint).show();
229
- this.showSuccess($root);
230
- },
321
+ const $row = $root.closest(giftcardRow);
322
+ const count = $row.find(`${chipList} ${chip}`).length;
323
+ const zeroTotal = this.summaryTotal != null ? isZeroAmount(this.summaryTotal) : false;
231
324
 
232
- handleToggleClick(e) {
233
- e.preventDefault();
234
- this.open($(e.currentTarget).closest(this.el.$blocks));
235
- },
325
+ if (count === 0) {
326
+ $root.find(hint)[zeroTotal ? 'hide' : 'show']();
327
+ return;
328
+ }
236
329
 
237
- handleCloseClick(e) {
238
- e.preventDefault();
239
- const $root = $(e.currentTarget).closest(this.el.$blocks);
240
- this.resetForm($root);
241
- this.close($root);
242
- },
330
+ this.updateHintVisibility($root);
331
+ }, 1000);
332
+ },
243
333
 
244
- finalizeSuccess($root, $success) {
245
- let { panel, toggle, hint, expandedAttr } = this.el;
334
+ showSubmitSpinner($root) {
335
+ const { panel, toggle, hint, expandedAttr } = this.el;
246
336
 
247
- if ($success && $success.length) {
248
- $success.attr('hidden', 'hidden').removeClass('fade show').off('transitionend');
249
- }
337
+ $root.find(panel).prop('hidden', true);
338
+ $root.find(toggle).attr(expandedAttr, 'false').show().trigger('focus');
339
+ $root.find(hint).show();
250
340
 
251
- this.resetForm($root);
252
- $root.find(panel).prop('hidden', true);
253
- $root.find(toggle).attr(expandedAttr, 'false').show();
254
- $root.find(hint).show();
341
+ this.lockPaymentsForSuccess($root);
255
342
 
256
- if (this.pendingServerGiftCards) {
257
- this.renderGiftCardsFromList($root, this.pendingServerGiftCards);
258
- this.pendingServerGiftCards = null;
259
- }
343
+ this.showSuccess($root);
344
+ },
260
345
 
261
- this.updateHintVisibility($root);
262
- this.successTimer = null;
263
- },
346
+ handleToggleClick(e) {
347
+ e.preventDefault();
348
+
349
+ const $root = $(e.currentTarget).closest(this.el.block);
350
+ const $container = $root.closest(this.el.checkoutContainer);
351
+
352
+ if (
353
+ $container.length &&
354
+ this.isCardMethodSelected($container) &&
355
+ this.isPaypageOpen($container)
356
+ ) {
357
+ this.clearPaypageAndCollapse($container);
358
+ }
359
+
360
+ this.open($root);
361
+ this.updateCtaButton($root);
362
+ },
363
+
364
+ handleCloseClick(e) {
365
+ e.preventDefault();
366
+ const $root = $(e.currentTarget).closest(this.el.block);
367
+ this.resetForm($root);
368
+ this.close($root);
369
+ },
370
+
371
+ finalizeSuccess($root, $success) {
372
+ if ($success && $success.length) {
373
+ $success.attr('hidden', 'hidden').removeClass('fade show').off('transitionend');
374
+ }
264
375
 
265
- showSuccess($root) {
266
- const { success } = this.el;
376
+ this.resetForm($root);
377
+
378
+ if (Array.isArray(this.pendingServerGiftCards)) {
379
+ this.renderGiftCardsFromList($root, this.pendingServerGiftCards);
380
+ this.pendingServerGiftCards = null;
381
+ } else {
382
+ this.updateHintVisibility($root);
383
+ }
384
+
385
+ this.successTimer = null;
386
+ },
387
+
388
+ lockPaymentsForSuccess($root) {
389
+ const $giftcard = $root.closest(this.el.block);
390
+ const $container = $giftcard.closest(this.el.checkoutContainer);
391
+
392
+ this.toggleAltPayments($giftcard, false);
393
+ this.toggleAltPaymentInfos($giftcard, false);
394
+
395
+ $container.find(this.el.billingAddress).show();
396
+
397
+ $container
398
+ .find(this.el.altPaymentRowsAttr)
399
+ .closest(this.el.formRow)
400
+ .hide();
401
+
402
+ this.altPaymentPanelsLocked = true;
403
+ this.altPaymentInfosLocked = true;
404
+ },
405
+
406
+
407
+ showSuccess($root) {
408
+ const { success } = this.el;
267
409
 
268
410
  if (this.successTimer) {
269
411
  clearTimeout(this.successTimer);
@@ -276,18 +418,19 @@ Wick.GiftCard = {
276
418
  $success[0] && $success[0].offsetWidth;
277
419
  $success.addClass('show');
278
420
 
279
- this.successTimer = setTimeout(() => {
280
- $success.removeClass('show');
281
- const handler = () => this.finalizeSuccess($root, $success);
421
+ this.successTimer = setTimeout(() => {
422
+ $success.removeClass('show');
282
423
 
283
- $success.on('transitionend', handler);
284
- setTimeout(handler, 200);
285
- }, 3000);
286
- },
424
+ const handler = () => this.finalizeSuccess($root, $success);
425
+ $success.on('transitionend', handler);
426
+
427
+ setTimeout(handler, 200);
428
+ }, 3000);
429
+ },
287
430
 
288
- handleFormSubmit(e) {
289
- const { number, block, giftcardRow, loaderChip } = this.el;
290
- e.preventDefault();
431
+ handleFormSubmit(e) {
432
+ const { number, block } = this.el;
433
+ e.preventDefault();
291
434
 
292
435
  const $root = $(e.currentTarget).closest(block);
293
436
  this.hideBanner($root);
@@ -298,50 +441,46 @@ Wick.GiftCard = {
298
441
  const $numInput = $root.find(this.el.number);
299
442
  const $pinInput = $root.find(this.el.pin);
300
443
 
301
- const numberBlurOpts = {
302
- fieldSelector: this.el.field,
303
- errorTextSelector: this.el.errorText,
304
- errorClass: this.el.fieldError,
305
- ariaInvalidAttr: this.el.ariaInvalidAttr,
306
- numberMessage: this.messages.numberMessage,
307
- };
308
-
309
- const pinBlurOpts = {
310
- fieldSelector: this.el.field,
311
- errorTextSelector: this.el.errorText,
312
- errorClass: this.el.fieldError,
313
- ariaInvalidAttr: this.el.ariaInvalidAttr,
314
- pinMessage: this.messages.pinMessage,
315
- };
316
-
317
- const okNumber = validateExactDigits($numInput, 16, this.messages.numberMessage, this.el);
318
- const okPin = validateExactDigits($pinInput, 8, this.messages.pinMessage, this.el);
319
-
320
- if (!(okNumber && okPin)) {
321
- handleGcNumberBlur({ currentTarget: $numInput[0] }, numberBlurOpts);
322
- handleGcPinBlur({ currentTarget: $pinInput[0] }, pinBlurOpts);
323
- (!okNumber ? $numInput : $pinInput).trigger('focus');
324
- return;
325
- }
326
-
327
- const giftCardNumber = this.getNumberValue($root);
328
- const pin = this.getPinValue($root);
329
- const $row = $root.closest(giftcardRow);
330
-
331
- let $loader = $row.children(loaderChip);
332
-
333
- if (!$loader.length) {
334
- appendLoader({ wrapper: $row });
335
- $loader = $row.children(loaderChip).last();
336
- }
337
-
338
- verifyGiftCard($loader, giftCardNumber, pin)
339
- .then((res) => this.handleVerifyResponse($root, res))
340
- .catch((err) => {
341
- const msg = this.getErrorMessage(err);
342
- this.showBannerError($root, msg);
343
- });
344
- },
444
+ const okNumber = validateExactDigits($numInput, 16, this.messages.numberMessage, this.el);
445
+ const okPin = validateExactDigits($pinInput, 8, this.messages.pinMessage, this.el);
446
+
447
+ if (!(okNumber && okPin)) {
448
+ handleGcNumberBlur({ currentTarget: $numInput[0] }, {
449
+ fieldSelector: this.el.field,
450
+ errorTextSelector: this.el.errorText,
451
+ errorClass: this.el.fieldError,
452
+ ariaInvalidAttr: this.el.ariaInvalidAttr,
453
+ numberMessage: this.messages.numberMessage,
454
+ });
455
+
456
+ handleGcPinBlur({ currentTarget: $pinInput[0] }, {
457
+ fieldSelector: this.el.field,
458
+ errorTextSelector: this.el.errorText,
459
+ errorClass: this.el.fieldError,
460
+ ariaInvalidAttr: this.el.ariaInvalidAttr,
461
+ pinMessage: this.messages.pinMessage,
462
+ });
463
+
464
+ (!okNumber ? $numInput : $pinInput).trigger('focus');
465
+ return;
466
+ }
467
+
468
+ const giftCardNumber = this.getNumberValue($root);
469
+ const pin = this.getPinValue($root);
470
+
471
+ const $pageLoader = this.getPageLoader();
472
+ showLoader($pageLoader);
473
+
474
+ verifyGiftCard($pageLoader, giftCardNumber, pin)
475
+ .then((res) => this.handleVerifyResponse($root, res))
476
+ .catch((err) => {
477
+ const msg = this.getErrorMessage(err);
478
+ this.showBannerError($root, msg);
479
+ })
480
+ .finally(() => {
481
+ hideLoader($pageLoader);
482
+ });
483
+ },
345
484
 
346
485
  handleVerifyResponse($root, res) {
347
486
  if (res && res.code === OK_CODE) {
@@ -350,15 +489,18 @@ Wick.GiftCard = {
350
489
  return;
351
490
  }
352
491
 
353
- this.pendingServerGiftCards = res.giftCards.slice();
492
+ let summaryData;
493
+ if (res.orderTotal != null || res.giftCardTotal != null) {
494
+ summaryData = { total: res.orderTotal, giftCardApplied: res.giftCardTotal };
354
495
 
355
- if (res.orderTotal != null || res.giftCardTotal != null) {
356
- const data = { total: res.orderTotal, giftCardApplied: res.giftCardTotal };
357
- updateOrderSummary(data, buildSummaryEqualMap(data), true);
358
- this.summaryTotal = res.orderTotal;
359
- this.toggleBillingDescrForZero($root);
360
- this.updateCtaButton($root);
361
- }
496
+ updateOrderSummary(summaryData, buildSummaryEqualMap(summaryData), true);
497
+ this.summaryTotal = res.orderTotal;
498
+
499
+ this.toggleBillingDescrForZero($root);
500
+ this.updateCtaButton($root);
501
+ }
502
+
503
+ this.pendingServerGiftCards = res.giftCards.slice();
362
504
 
363
505
  this.resetForm($root);
364
506
  this.showSubmitSpinner($root);
@@ -369,72 +511,70 @@ Wick.GiftCard = {
369
511
  this.showBannerError($root, msg);
370
512
  },
371
513
 
372
- updateHintVisibility($root) {
373
- const {
374
- chipList,
375
- giftcardRow,
376
- hint,
377
- panel,
378
- toggle,
379
- iconInfo,
380
- expandedAttr,
381
- summaryHint,
382
- chip,
383
- block,
384
- body,
385
- } = this.el;
514
+ updateHintVisibility($root, opts = {}) {
515
+ const {
516
+ chipList,
517
+ giftcardRow,
518
+ hint,
519
+ panel,
520
+ toggle,
521
+ iconInfo,
522
+ expandedAttr,
523
+ summaryHint,
524
+ chip,
525
+ block,
526
+ body,
527
+ fieldError,
528
+ } = this.el;
386
529
 
387
- const $row = $root.closest(giftcardRow);
388
- const $giftcard = $row.find(block).first();
389
- const count = $row.find(`${chipList} ${chip}`).length;
390
- const limit = this.maxChips || 3;
530
+ const { skipResetForm = false } = opts;
391
531
 
392
- const zeroTotal = this.summaryTotal != null ? isZeroAmount(this.summaryTotal) : false;
532
+ const $giftcard = $root.closest(block).length ? $root.closest(block) : $root;
533
+ const $summary = this.ensureSummaryContainer($giftcard);
534
+ const count = $summary.find(`${chipList} ${chip}`).length;
393
535
 
394
- this.toggleAltPayments($giftcard, count === 0);
395
- this.toggleAltPaymentInfos($giftcard, count === 0);
536
+ const limit = this.maxChips || 3;
537
+ const zeroTotal = this.summaryTotal != null ? isZeroAmount(this.summaryTotal) : false;
396
538
 
397
- if (count > 0) {
398
- if (!this.altPaymentPanelsLocked) {
399
- this.showOnlyBillingAddress($giftcard);
400
- this.altPaymentPanelsLocked = true;
401
- } else {
402
- this.showOnlyBillingAddress($giftcard);
403
- }
404
- } else {
405
- if (!this.altPaymentPanelsLocked) {
406
- this.toggleAltPayments($giftcard, true);
407
- this.toggleAltPaymentInfos($giftcard, true);
408
- } else {
409
- this.showOnlyBillingAddress($giftcard);
410
- }
411
- }
539
+ this.toggleAltPayments($giftcard, count === 0);
540
+ this.toggleAltPaymentInfos($giftcard, count === 0);
412
541
 
413
- const $summary = this.ensureSummaryContainer($giftcard);
542
+ if (count === 0) {
543
+ $summary.hide();
414
544
 
415
- if (count === 0) {
416
- $summary.hide();
417
- $giftcard.show();
418
- this.resetForm($giftcard);
419
- $giftcard.find(panel).prop('hidden', true);
420
- $giftcard.find(toggle).attr(expandedAttr, 'false').show();
421
- $giftcard.find(hint)[zeroTotal ? 'hide' : 'show']();
422
- this.updateCtaButton($giftcard);
423
- return;
424
- }
545
+ $giftcard.show();
425
546
 
426
- this.setBillingLabelToCard($giftcard);
427
- $summary.show();
428
- $giftcard.hide();
429
- $giftcard.find(hint).hide();
547
+ if (!skipResetForm) {
548
+ this.resetForm($giftcard);
549
+ }
550
+
551
+ $giftcard.find(panel).prop('hidden', true);
552
+ $giftcard.find(toggle).attr(expandedAttr, 'false').show();
553
+ $giftcard.find(hint)[zeroTotal ? 'hide' : 'show']();
554
+
555
+ this.updateCtaButton($giftcard);
556
+ return;
557
+ }
430
558
 
431
- const ctx = buildHintContext(count, limit, zeroTotal);
432
- const html = giftCardsHint(ctx);
433
- const $old = $summary.find(summaryHint).first();
434
- const $new = $(html);
559
+ this.setBillingLabelToCard($giftcard);
435
560
 
436
- if ($old.length) $old.replaceWith($new);
437
- else $summary.append($new);
561
+ $summary.show();
562
+ $giftcard.find(hint).hide();
563
+ const panelOpen = this.isPanelOpen($giftcard);
564
+ const hasError = $giftcard.find(`.${fieldError}`).length > 0;
565
+
566
+ const shouldHideGiftcard = count > 0 && !panelOpen && !hasError;
567
+
568
+ $giftcard.toggle(!shouldHideGiftcard);
569
+
570
+ const ctx = buildHintContext(count, limit, zeroTotal);
571
+ const html = giftCardsHint(ctx);
572
+
573
+ const $old = $summary.find(summaryHint).first();
574
+ const $new = $(html);
575
+
576
+ if ($old.length) $old.replaceWith($new);
577
+ else $summary.append($new);
438
578
 
439
579
  if (zeroTotal) {
440
580
  $summary.find(summaryHint).hide();
@@ -451,19 +591,27 @@ Wick.GiftCard = {
451
591
  return giftCardChip({ id, maskedNumber, currency, amount });
452
592
  },
453
593
 
454
- toggleAltPaymentInfos($root, show) {
455
- const { checkoutContainer, billieInfo, klarnaInfo } = this.el;
456
- const $container = $root.closest(checkoutContainer);
594
+ toggleAltPaymentInfos($root, show) {
595
+ const {
596
+ checkoutContainer,
597
+ billieInfo,
598
+ klarnaInfo,
599
+ paymentMethodCheckedSel,
600
+ } = this.el;
601
+
602
+ const $container = $root.closest(checkoutContainer);
457
603
 
458
604
  if (this.altPaymentInfosLocked) {
459
605
  show = false;
460
606
  }
461
607
 
462
- [$container.find(billieInfo), $container.find(klarnaInfo)].forEach(($panel) => {
463
- if ($panel && $panel.length) {
464
- $panel[show ? 'show' : 'hide']();
465
- }
466
- });
608
+ const currentMethod = $container.find(paymentMethodCheckedSel).val();
609
+
610
+ const showBillie = show && currentMethod === 'billie';
611
+ const showKlarna = show && currentMethod === 'klarna';
612
+
613
+ $container.find(billieInfo)[showBillie ? 'show' : 'hide']();
614
+ $container.find(klarnaInfo)[showKlarna ? 'show' : 'hide']();
467
615
 
468
616
  if (!show) this.altPaymentInfosLocked = true;
469
617
  },
@@ -530,24 +678,104 @@ Wick.GiftCard = {
530
678
  }
531
679
  },
532
680
 
533
- handleAddAnotherClick(e) {
534
- e.preventDefault();
535
- const { giftcardRow, chipList, chip, block, number, summaryHint } = this.el;
536
-
537
- const $row = $(e.currentTarget).closest(giftcardRow);
538
- const count = $row.find(`${chipList} ${chip}`).length;
539
- if (count >= this.maxChips) return;
540
-
541
- const $giftcard = $row.find(block).first();
542
- this.resetForm($giftcard);
543
- this.open($giftcard);
544
-
545
- $row.find(summaryHint).hide();
546
-
547
- setTimeout(() => {
548
- $giftcard.find(number).trigger('focus');
549
- }, 0);
550
- },
681
+ handleAddAnotherClick(e) {
682
+ e.preventDefault();
683
+
684
+ const {
685
+ giftcardRow,
686
+ chipList,
687
+ chip,
688
+ block,
689
+ number,
690
+ pin,
691
+ summaryHint,
692
+ checkoutContainer,
693
+ fieldError,
694
+ notificationRoot,
695
+ } = this.el;
696
+
697
+ const $row = $(e.currentTarget).closest(giftcardRow);
698
+
699
+ const $container = $row.closest(checkoutContainer);
700
+ if (
701
+ $container.length &&
702
+ this.isCardMethodSelected($container) &&
703
+ this.isPaypageOpen($container)
704
+ ) {
705
+ this.clearPaypageAndCollapse($container);
706
+ }
707
+
708
+ const count = $row.find(`${chipList} ${chip}`).length;
709
+ if (count >= this.maxChips) return;
710
+
711
+ const $giftcard = $row.find(block).first();
712
+
713
+ const hasDraft =
714
+ String($giftcard.find(number).val() || '').trim().length > 0 ||
715
+ String($giftcard.find(pin).val() || '').trim().length > 0;
716
+
717
+ const hasFieldError = $giftcard.find(`.${fieldError}`).length > 0;
718
+ const hasBannerError = $giftcard.find(notificationRoot).length > 0;
719
+
720
+ if (!hasDraft && !hasFieldError && !hasBannerError) {
721
+ this.resetForm($giftcard);
722
+ }
723
+
724
+ this.open($giftcard);
725
+ $row.find(summaryHint).hide();
726
+
727
+ setTimeout(() => {
728
+ $giftcard.find(number).trigger('focus');
729
+ }, 0);
730
+ },
731
+
732
+ isCardMethodSelected($container) {
733
+ const { paymentMethodCheckedSel, paymentMethodCardValue } = this.el;
734
+
735
+ const $checked = $container.find(paymentMethodCheckedSel);
736
+ return $checked.length && $checked.val() === paymentMethodCardValue;
737
+ },
738
+
739
+ isPaypageOpen($container) {
740
+ const { paypageNewCardSel, paypageIframeWrapSel } = this.el;
741
+
742
+ const $newCard = $container.find(paypageNewCardSel);
743
+ if ($newCard.length) {
744
+ return $newCard.is(':visible');
745
+ }
746
+
747
+ const $wrap = $container.find(paypageIframeWrapSel);
748
+ return $wrap.length ? $wrap.is(':visible') : false;
749
+ },
750
+
751
+
752
+ clearPaypageAndCollapse($container) {
753
+ const {
754
+ cardDetails,
755
+ hiddenCard,
756
+ paypageNewCardSel,
757
+ paypageExistingCardSel,
758
+ paypageIframeWrapSel,
759
+ cardValidationErrorRowSel,
760
+ cardValidationErrorRowClass,
761
+ cardValidationErrorTextSel,
762
+ } = this.el;
763
+
764
+ const $cardDetails = $container.find(cardDetails);
765
+ if (!$cardDetails.length) return;
766
+
767
+ $container.find(paypageNewCardSel).hide();
768
+ $container.find(paypageExistingCardSel).show();
769
+
770
+ $cardDetails.addClass(hiddenCard).hide();
771
+ $cardDetails.find(paypageIframeWrapSel).hide();
772
+
773
+ $cardDetails
774
+ .find(cardValidationErrorRowSel)
775
+ .removeClass(cardValidationErrorRowClass)
776
+ .find(cardValidationErrorTextSel)
777
+ .remove();
778
+ },
551
779
 
552
780
  getErrorMessage(payload) {
553
781
  const code =
@@ -558,38 +786,42 @@ Wick.GiftCard = {
558
786
  return (code != null && MESSAGE_BY_CODE[code]) || DEFAULT_ERROR_MESSAGE;
559
787
  },
560
788
 
561
- handleChipCloseClick(e) {
562
- e.preventDefault();
563
- const { chip, giftcardRow, block, giftcardChipClose, chipList, loaderChip } = this.el;
789
+ handleChipCloseClick(e) {
790
+ e.preventDefault();
791
+
792
+ const {
793
+ chip,
794
+ giftcardRow,
795
+ block,
796
+ giftcardChipClose,
797
+ chipList,
798
+ } = this.el;
564
799
 
565
800
  const $clickedChip = $(e.currentTarget).closest(chip);
566
801
  const $row = $clickedChip.closest(giftcardRow);
567
802
  const $giftcard = $row.find(block).first();
568
803
  const $summary = this.ensureSummaryContainer($giftcard);
569
804
 
570
- const $chips = $summary.find(`${chipList} ${chip}`);
571
- const index = $chips.index($clickedChip);
572
- if (index < 0) return;
573
-
574
- let $loader = $row.children(loaderChip);
575
- if (!$loader.length) {
576
- appendLoader({ wrapper: $row });
577
- $loader = $row.children(loaderChip).last();
578
- }
805
+ const $chips = $summary.find(`${chipList} ${chip}`);
806
+ const index = $chips.index($clickedChip);
807
+ if (index < 0) return;
579
808
 
580
809
  $row.find(giftcardChipClose).css('pointer-events', 'none').attr('aria-disabled', 'true');
581
810
 
582
- removeGiftCard($loader, index)
583
- .then((res) => this.handleRemoveResponse($giftcard, res))
584
- .catch((err) => {
585
- const msg = this.getErrorMessage(err);
586
- this.showBannerError($giftcard, msg);
587
- })
588
- .finally(() => {
589
- hideLoader($loader);
590
- $row.find(giftcardChipClose).css('pointer-events', '').removeAttr('aria-disabled');
591
- });
592
- },
811
+ const $pageLoader = this.getPageLoader();
812
+ showLoader($pageLoader);
813
+
814
+ removeGiftCard($pageLoader, index)
815
+ .then((res) => this.handleRemoveResponse($giftcard, res))
816
+ .catch((err) => {
817
+ const msg = this.getErrorMessage(err);
818
+ this.showBannerError($giftcard, msg);
819
+ })
820
+ .finally(() => {
821
+ hideLoader($pageLoader);
822
+ $row.find(giftcardChipClose).css('pointer-events', '').removeAttr('aria-disabled');
823
+ });
824
+ },
593
825
 
594
826
  handleRemoveResponse($giftcard, res) {
595
827
  if (res && res.code === OK_CODE) {
@@ -624,16 +856,16 @@ Wick.GiftCard = {
624
856
  return $summary;
625
857
  },
626
858
 
627
- getPageLoader() {
628
- const $pl = $(this.el.pageLoader);
629
- if (!$pl.parent().is('body')) $pl.appendTo('body');
630
- return $pl;
631
- },
859
+ getPageLoader() {
860
+ const $pageLoader = $(this.el.pageLoader);
861
+ if (!$pageLoader.parent().is('body')) $pageLoader.appendTo('body');
862
+ return $pageLoader;
863
+ },
632
864
 
633
- showPageLoader() {
634
- const $pl = this.getPageLoader();
635
- showLoader($pl);
636
- },
865
+ showPageLoader() {
866
+ const $pageLoader = this.getPageLoader();
867
+ showLoader($pageLoader);
868
+ },
637
869
 
638
870
  updateCtaButton($scope) {
639
871
  const { ctaSelector, btnDetails, btnText, checkoutContainer } = this.el;
@@ -710,20 +942,20 @@ Wick.GiftCard = {
710
942
  (error.errorCode && PAY_MESSAGE_BY_CODE[error.errorCode]) ||
711
943
  DEFAULT_PAY_ERROR_MESSAGE;
712
944
 
713
- if (msg) {
714
- Wick.Notification.show({
715
- text: linkifyClickHere(msg),
716
- container: '.globalMessages .container',
717
- type: 'error',
718
- });
719
- }
720
- })
721
- .finally(() => {
722
- const $pl = self.getPageLoader();
723
- hideLoader($pl);
724
- });
945
+ if (msg) {
946
+ Wick.Notification.show({
947
+ text: linkifyClickHere(msg),
948
+ container: '.globalMessages .container',
949
+ type: 'error',
950
+ });
951
+ }
952
+ })
953
+ .finally(() => {
954
+ const $pageLoader = self.getPageLoader();
955
+ hideLoader($pageLoader);
725
956
  });
726
- },
957
+ });
958
+ },
727
959
 
728
960
  showBannerError($root, message, title = '') {
729
961
  const { notificationRoot, giftCardInline, inlineHeader } = this.el;
@@ -739,8 +971,34 @@ Wick.GiftCard = {
739
971
  text: linkifyClickHere(message),
740
972
  });
741
973
 
742
- $inline.find(inlineHeader).after(html);
743
- },
974
+ $inline.find(inlineHeader).after(html);
975
+ },
976
+
977
+ clearErrorsOnly($root) {
978
+ const { number, pin, note, field, errorText, fieldError, ariaInvalidAttr } = this.el;
979
+
980
+ const $num = $root.find(number);
981
+ const $pin = $root.find(pin);
982
+
983
+ clearErrorText($num, field, errorText, fieldError, ariaInvalidAttr);
984
+ clearErrorText($pin, field, errorText, fieldError, ariaInvalidAttr);
985
+
986
+ $root.find(note).remove();
987
+
988
+ this.hideBanner($root);
989
+ },
990
+
991
+ clearErrorsIfEmptyOnInit($root) {
992
+ const rawNum = String($root.find(this.el.number).val() || '');
993
+ const rawPin = String($root.find(this.el.pin).val() || '');
994
+
995
+ const digitsNum = rawNum.replace(/\D/g, '');
996
+ const digitsPin = rawPin.replace(/\D/g, '');
997
+
998
+ if (digitsNum || digitsPin) return;
999
+
1000
+ this.clearErrorsOnly($root);
1001
+ },
744
1002
 
745
1003
  hideBanner($root) {
746
1004
  const { notification } = this.el;
@@ -766,9 +1024,9 @@ Wick.GiftCard = {
766
1024
  const $list = $summary.find(chipList);
767
1025
  $list.children(`${chip}:not(${loaderChip})`).remove();
768
1026
 
769
- const html = (giftCards || [])
770
- .map((g) => this.renderChipHTML(this.mapGiftToChipData($root, g)))
771
- .join('');
1027
+ const html = (giftCards || [])
1028
+ .map((giftCard) => this.renderChipHTML(this.mapGiftToChipData($root, giftCard)))
1029
+ .join('');
772
1030
 
773
1031
  if (html) {
774
1032
  $list.append(html);
@@ -803,13 +1061,31 @@ Wick.GiftCard = {
803
1061
  }
804
1062
  },
805
1063
 
806
- showOnlyBillingAddress($root) {
807
- const { checkoutContainer, billingAddress, altPaymentRowsAttr, hiddenCard } = this.el;
808
- const $container = $root.closest(checkoutContainer);
809
- $container.find(billingAddress).removeClass(hiddenCard);
810
- $container.find(altPaymentRowsAttr).addClass(hiddenCard);
811
- this.toggleAltPaymentInfos($root, false);
812
- },
1064
+ showOnlyBillingAddress($root) {
1065
+ const {
1066
+ checkoutContainer,
1067
+ billingAddress,
1068
+ altPaymentRowsAttr,
1069
+ hiddenCard,
1070
+ } = this.el;
1071
+
1072
+ const $container = $root.closest(checkoutContainer);
1073
+ if (!$container.length) {
1074
+ return;
1075
+ }
1076
+
1077
+ $container.find(billingAddress).removeClass(hiddenCard).show();
1078
+
1079
+ $container.find(altPaymentRowsAttr).addClass(hiddenCard);
1080
+
1081
+ if (this.isCardMethodSelected($container)) {
1082
+ this.clearPaypageAndCollapse($container);
1083
+ } else {
1084
+ $container.find(this.el.cardDetails).addClass(hiddenCard);
1085
+ }
1086
+
1087
+ this.toggleAltPaymentInfos($root, false);
1088
+ },
813
1089
 
814
1090
  useGlobalError($root, message) {
815
1091
  if (window.Wick && Wick.Notification && typeof Wick.Notification.show === 'function') {
@@ -836,16 +1112,80 @@ Wick.GiftCard = {
836
1112
  return;
837
1113
  }
838
1114
 
839
- const msg = PAY_MESSAGE_BY_CODE[code] || DEFAULT_PAY_ERROR_MESSAGE;
840
- this.useGlobalError(this.el.$blocks.first(), msg);
841
- });
842
- },
1115
+ const msg = PAY_MESSAGE_BY_CODE[code] || DEFAULT_PAY_ERROR_MESSAGE;
1116
+ this.useGlobalError(this.el.$blocks.first(), msg);
1117
+ });
1118
+ },
1119
+
1120
+ collapseGiftcardPanel($container, opts = {}) {
1121
+ const { hideIfHasChips = false } = opts;
1122
+ const { panel, toggle, expandedAttr, checkoutContainer, block } = this.el;
1123
+
1124
+ const $ctx = $container && $container.length ? $container : $(checkoutContainer).first();
1125
+ const $giftcard = $ctx.find(block).first();
1126
+ if (!$giftcard.length) return;
1127
+
1128
+ $giftcard.find(panel).prop('hidden', true).hide();
1129
+ $giftcard.find(toggle).attr(expandedAttr, 'false');
1130
+
1131
+ this.updateHintVisibility($giftcard, { skipResetForm: true });
1132
+
1133
+ if (hideIfHasChips) {
1134
+ const hasChips = this.getAppliedChipsCount($giftcard) > 0;
1135
+ if (hasChips) {
1136
+ $giftcard.hide();
1137
+ $giftcard.find(toggle).hide();
1138
+ } else {
1139
+ $giftcard.show();
1140
+ $giftcard.find(toggle).show();
1141
+ }
1142
+ } else {
1143
+ $giftcard.find(toggle).show();
1144
+ }
1145
+ },
1146
+
1147
+ bindCtaCardCollapse() {
1148
+ const sel = this.el.btnEnterDetails;
1149
+
1150
+ $(document).off('click.giftcardCardCollapse', sel);
1151
+
1152
+ $(document).on('click.giftcardCardCollapse', sel, (e) => {
1153
+ const $btn = $(e.currentTarget);
1154
+ const mode = $btn.attr('data-mode');
1155
+ if (mode !== 'card') return;
1156
+
1157
+ const $container = $btn.closest(this.el.checkoutContainer);
1158
+
1159
+ console.log('[GC] CTA click', {
1160
+ mode,
1161
+ btnFound: $(e.currentTarget).length,
1162
+ container: $btn.closest(this.el.checkoutContainer).length,
1163
+ });
1164
+
1165
+ if (!$container.length) return;
1166
+
1167
+ e.preventDefault();
1168
+
1169
+ this.collapseGiftcardPanel($container, { hideIfHasChips: true });
1170
+
1171
+ this.openPaypage($container);
1172
+ });
1173
+ },
1174
+
843
1175
 
844
1176
  bindEvents() {
845
1177
  const { number, pin, toggle, closeBtn, giftcardBtn, jsGiftcardAdd, giftcardChipClose } =
846
1178
  this.el;
847
1179
 
848
- $(document).off('.giftcard');
1180
+ $(document).off('.giftcard');
1181
+
1182
+ $(document).off('focusin.giftcard', this.collapseTargets);
1183
+ $(document).on('focusin.giftcard', this.collapseTargets, (e) => this.handleCollapseTrigger(e));
1184
+
1185
+ $(document).off('change.giftcard', '#chb-payment-details-card');
1186
+ $(document).on('change.giftcard', '#chb-payment-details-card', (e) => this.handleCollapseTrigger(e));
1187
+
1188
+
849
1189
 
850
1190
  const handleNumberInput = createGcNumberInputHandler({
851
1191
  fieldSelector: this.el.field,
@@ -897,8 +1237,9 @@ Wick.GiftCard = {
897
1237
  .on('click.giftcard', jsGiftcardAdd, this.handleAddAnotherClick.bind(this))
898
1238
  .on('click.giftcard', giftcardChipClose, this.handleChipCloseClick.bind(this));
899
1239
 
900
- this.bindGiftcardCtaHandler();
901
- },
1240
+ this.bindGiftcardCtaHandler();
1241
+ this.bindCtaCardCollapse();
1242
+ },
902
1243
 
903
1244
  init(payload = {}) {
904
1245
  const { field, pin, $blocks } = this.el;
@@ -917,11 +1258,14 @@ Wick.GiftCard = {
917
1258
  }
918
1259
  }
919
1260
 
920
- $blocks.each((index, block) => {
921
- const $pinField = $(block).find(pin).closest(field);
922
- if ($pinField.length) {
923
- initializeInputToggle($pinField);
924
- }
925
- });
926
- },
1261
+ $blocks.each((index, block) => {
1262
+ const $block = $(block);
1263
+ this.clearErrorsIfEmptyOnInit($block);
1264
+
1265
+ const $pinField = $block.find(pin).closest(field);
1266
+ if ($pinField.length) {
1267
+ initializeInputToggle($pinField);
1268
+ }
1269
+ });
1270
+ }
927
1271
  };