wickes-css2 2.113.0-develop.7 → 2.113.0-develop.8

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 (150) hide show
  1. package/build/css/components/price-block-v2-critical.css +1 -1
  2. package/build/css/components/price-block-v2.css +1 -1
  3. package/build/css/kitchen-plp-main.css +1 -1
  4. package/build/css/main.css +1 -1
  5. package/build/css/my-account-main-v2.css +1 -1
  6. package/build/css/my-account-main.css +1 -1
  7. package/build/css/pages/page_product-details-v2-critical.css +1 -1
  8. package/build/css/pages/page_product-details-v2.css +1 -1
  9. package/build/css/pages/page_product-details.css +1 -1
  10. package/build/css/pdp-main-before-combine.css +1 -1
  11. package/build/css/pdp-main-critical.css +1 -1
  12. package/build/css/pdp-main-non-critical.css +1 -1
  13. package/build/css/pdp-main.css +1 -1
  14. package/build/css/plp-main.css +1 -1
  15. package/build/js/account-members.min.js +1 -1
  16. package/build/js/add-project-list-id.min.js +1 -1
  17. package/build/js/address-book.min.js +1 -1
  18. package/build/js/basket.min.js +2 -2
  19. package/build/js/bundle.min.js +1 -1
  20. package/build/js/change-password.min.js +1 -1
  21. package/build/js/checkout.min.js +2 -2
  22. package/build/js/emulation.min.js +238 -190
  23. package/build/js/general.bundle.min.js +1 -1
  24. package/build/js/gift-cards.min.js +1 -1
  25. package/build/js/kitchen/kitchen-plp.min.js +1 -1
  26. package/build/js/merged-checkout.min.js +2 -2
  27. package/build/js/package-bulk-add.min.js +1 -0
  28. package/build/js/page/plp-load-more.js +81 -66
  29. package/build/js/page/ripple/bulk-add.js +71 -0
  30. package/build/js/page/ripple/package-bulk-add.js +43 -0
  31. package/build/js/page/ripple/postcode-checker.js +83 -0
  32. package/build/js/page/ripple/thumb-gallery.js +168 -0
  33. package/build/js/page/utils/validation.js +1 -1
  34. package/build/js/pdp.bundle.min.js +2 -2
  35. package/build/js/personal-details.min.js +1 -1
  36. package/build/js/plp.bundle.min.js +1 -1
  37. package/build/js/postcode-checker.min.js +1 -0
  38. package/build/js/project-list.min.js +2 -2
  39. package/build/js/quiz.min.js +1 -1
  40. package/build/js/track-my-order.min.js +1 -1
  41. package/package.json +1 -1
  42. package/src/badges-ripple.html +120 -0
  43. package/src/badges.html +9 -18
  44. package/src/components/fulfilment-accordions.hbs +1 -1
  45. package/src/components/image-accordion.hbs +18 -0
  46. package/src/components/kitchen/price.hbs +49 -29
  47. package/src/components/kitchen/strip-stickers.hbs +9 -3
  48. package/src/components/package-card.hbs +30 -0
  49. package/src/components/pdp-price-actions.hbs +17 -0
  50. package/src/components/postcode-checker.hbs +24 -0
  51. package/src/components/price-badges.hbs +12 -10
  52. package/src/components/price-block-v2.hbs +274 -202
  53. package/src/components/product-main-info-v2.hbs +2 -0
  54. package/src/components/suite-includes.hbs +66 -0
  55. package/src/components/suite-product-card.hbs +47 -0
  56. package/src/components/thumb-gallery.hbs +23 -0
  57. package/src/data/data_badges.json +143 -0
  58. package/src/data/data_bathroom-plp.json +814 -0
  59. package/src/data/data_suite-includes-products.json +134 -0
  60. package/src/js/components/banner-placement-manager.js +25 -9
  61. package/src/js/components/general/image-accordion.js +54 -0
  62. package/src/js/components/package-card.js +69 -0
  63. package/src/js/components/store-locator-cards.js +76 -0
  64. package/src/js/emulation/banner-placement-manager.js +219 -188
  65. package/src/js/emulation/plp-load-more.js +13 -4
  66. package/src/js/emulation/postcode-checker.js +11 -0
  67. package/src/js/page/plp-load-more.js +81 -66
  68. package/src/js/page/ripple/bulk-add.js +71 -0
  69. package/src/js/page/ripple/package-bulk-add.js +43 -0
  70. package/src/js/page/ripple/postcode-checker.js +83 -0
  71. package/src/js/page/ripple/thumb-gallery.js +168 -0
  72. package/src/js/page/utils/validation.js +1 -1
  73. package/src/page_bathroom-plp-vat.html +81 -0
  74. package/src/page_bathroom-plp-without-load-more.html +83 -0
  75. package/src/page_bathroom-plp.html +98 -0
  76. package/src/page_product-details-banner.html +1 -3
  77. package/src/page_product-details-big-wins-disabled-delivery.html +1 -3
  78. package/src/page_product-details-big-wins-non-registered.html +1 -3
  79. package/src/page_product-details-big-wins-out-nearest.html +1 -3
  80. package/src/page_product-details-big-wins-unhappy.html +1 -3
  81. package/src/page_product-details-big-wins.html +1 -3
  82. package/src/page_product-details-billie.html +1 -3
  83. package/src/page_product-details-calculator.html +1 -3
  84. package/src/page_product-details-cashback-v2.html +1 -3
  85. package/src/page_product-details-clearpay.html +1 -3
  86. package/src/page_product-details-cnc-error-notification.html +1 -3
  87. package/src/page_product-details-cnc-success-notification-vat.html +1 -4
  88. package/src/page_product-details-cnc-success-notification.html +1 -3
  89. package/src/page_product-details-default-store.html +1 -3
  90. package/src/page_product-details-energy-efficiency.html +1 -3
  91. package/src/page_product-details-flooring-with-pr-placeholder.html +1 -3
  92. package/src/page_product-details-flooring.html +1 -3
  93. package/src/page_product-details-gallery-actual.html +1 -3
  94. package/src/page_product-details-mfe-calculator.html +1 -3
  95. package/src/page_product-details-mtm-doors.html +1 -3
  96. package/src/page_product-details-only-clearpay.html +1 -3
  97. package/src/page_product-details-paint-mixing.html +1 -3
  98. package/src/page_product-details-ripple-gallery.html +121 -0
  99. package/src/page_product-details-saved-pl.html +1 -3
  100. package/src/page_product-details-suite-includes-banners.html +139 -0
  101. package/src/page_product-details-suite-includes-billie.html +128 -0
  102. package/src/page_product-details-suite-includes-klarna.html +120 -0
  103. package/src/page_product-details-suite-includes-vat.html +126 -0
  104. package/src/page_product-details-suite-includes.html +122 -0
  105. package/src/page_product-details-tile-steps-klarna-widget-with-method-ids.html +1 -3
  106. package/src/page_product-details-tile-steps-logout.html +1 -3
  107. package/src/page_product-details-tile-steps-no-new-project-list.html +1 -3
  108. package/src/page_product-details-tile-steps-with-klarna.html +1 -3
  109. package/src/page_product-details-tile-steps.html +1 -3
  110. package/src/page_product-details-v2.html +1 -3
  111. package/src/page_product-details-vat.html +1 -3
  112. package/src/page_product-details-wisdom-mcfc-registered.html +1 -3
  113. package/src/page_product-details-wisdom-mcfc.html +1 -3
  114. package/src/page_product-details-wisdom-oos-registered.html +1 -3
  115. package/src/page_product-details-wisdom-oos.html +1 -3
  116. package/src/page_product-details-wisdom-registered.html +1 -3
  117. package/src/page_product-details-wisdom.html +1 -3
  118. package/src/page_product-details-with-favourite.html +1 -3
  119. package/src/page_product-details-with-global-search-v2.html +2 -3
  120. package/src/page_product-details-with-why-not-add-single.html +1 -0
  121. package/src/page_product-details_no-previous-default.html +1 -3
  122. package/src/scss/components/_date-selection-add-new-styles.scss +29 -0
  123. package/src/scss/components/_image-accordion.scss +54 -0
  124. package/src/scss/components/_kitchen-card.scss +1 -0
  125. package/src/scss/components/_package-card.scss +63 -0
  126. package/src/scss/components/_package-plp.scss +88 -0
  127. package/src/scss/components/_postcode-checker.scss +115 -0
  128. package/src/scss/components/_price-badges-critical.scss +10 -0
  129. package/src/scss/components/_price-badges.scss +10 -0
  130. package/src/scss/components/_price-block-critical.scss +1 -0
  131. package/src/scss/components/_price-block.scss +1 -0
  132. package/src/scss/components/_suite-includes.scss +141 -0
  133. package/src/scss/components/_suite-product-card.scss +98 -0
  134. package/src/scss/components/_thumb-gallery-critical.scss +34 -0
  135. package/src/scss/components/_thumb-gallery.scss +192 -0
  136. package/src/scss/components/kitchen/_price.scss +10 -0
  137. package/src/scss/components/kitchen/_strip-stickers.scss +46 -0
  138. package/src/scss/components/price-block-v2-critical.scss +58 -0
  139. package/src/scss/components/price-block-v2.scss +58 -0
  140. package/src/scss/pages/page_product-details-v2-critical.scss +216 -109
  141. package/src/scss/pages/page_product-details-v2.scss +168 -107
  142. package/src/scss/pages/page_product-details.scss +11 -0
  143. package/src/scss/pdp-main-critical.scss +1 -0
  144. package/src/scss/pdp-main.scss +6 -0
  145. package/src/scss/plp-main.scss +5 -0
  146. package/src/sitemap.html +13 -0
  147. package/build/css/components/kitchen/strip-stickers.css +0 -1
  148. package/build/css/components/strip-stickers.css +0 -1
  149. package/src/scss/components/kitchen/strip-stickers.scss +0 -18
  150. package/src/scss/components/strip-stickers.scss +0 -18
@@ -1,77 +1,92 @@
1
- import {createEvent} from "./utils/create-event";
2
- import {appendLoader, showLoader, hideLoader} from "./utils/loader";
1
+ import { createEvent } from './utils/create-event';
2
+ import { appendLoader, showLoader, hideLoader } from './utils/loader';
3
3
 
4
4
  var Wick = window.Wick || {};
5
5
 
6
6
  Wick.PLPLoadMore = {
7
- PLP_LOAD_MORE_EVENT: 'loadMore',
8
- HIDDEN_CLASS_NAME: 'd-none',
9
- initialPageNumber: 0,
10
- el: {
11
- $loadMoreBtn: $('.btn-load-more'),
12
- loader: '.loader-wrapper',
13
- $sortOptions: $('#sort_form1'),
14
- productsList: '.products-list'
15
- },
16
- numberOfPagesPLP: $('#numberOfPagesPLP').val(),
17
- loaderPayload: {
18
- wrapper: 'body',
19
- hidden: true,
20
- modifier: 'basket-loader',
21
- },
22
- loadMore () {
23
- showLoader(Wick.PLPLoadMore.el.loader);
7
+ PLP_LOAD_MORE_EVENT: 'loadMore',
8
+ HIDDEN_CLASS_NAME: 'd-none',
9
+ MAX_PRODUCTS_PER_PAGE: 32,
10
+ initialPageNumber: 0,
11
+ el: {
12
+ $loadMoreBtn: $('.btn-load-more'),
13
+ loader: '.loader-wrapper',
14
+ $sortOptions: $('#sort_form1'),
15
+ productsList: $('.package-plp__cards').length ? '.package-plp__cards' : '.products-list',
16
+ $packageContent: $('.package-plp__content'),
17
+ },
18
+ numberOfPagesPLP: $('#numberOfPagesPLP').val(),
19
+ loaderPayload: {
20
+ wrapper: 'body',
21
+ hidden: true,
22
+ modifier: 'basket-loader',
23
+ },
24
+ loadMore() {
25
+ showLoader(Wick.PLPLoadMore.el.loader);
24
26
 
25
- return new Promise((resolve, reject) => {
26
- const eventDetail = {resolve, reject};
27
- const payload = {
28
- currentPage: ++Wick.PLPLoadMore.initialPageNumber,
29
- sort: Wick.PLPLoadMore.el.$sortOptions.val() || '',
30
- };
31
- const event = createEvent(Wick.PLPLoadMore.PLP_LOAD_MORE_EVENT, payload, eventDetail);
32
- window.dispatchEvent(event);
33
- })
34
- .then((response) => {
35
- if (!response.length) {
36
- return;
27
+ return new Promise((resolve, reject) => {
28
+ const eventDetail = { resolve, reject };
29
+ const payload = {
30
+ currentPage: ++Wick.PLPLoadMore.initialPageNumber,
31
+ sort: Wick.PLPLoadMore.el.$sortOptions.val() || '',
32
+ isRippleData: Wick.PLPLoadMore.el.$packageContent.length,
33
+ };
34
+ const event = createEvent(Wick.PLPLoadMore.PLP_LOAD_MORE_EVENT, payload, eventDetail);
35
+ window.dispatchEvent(event);
36
+ })
37
+ .then((response) => {
38
+ if (!response.length) {
39
+ return;
40
+ }
41
+
42
+ Wick.PLPLoadMore.showNewCards(response);
43
+ Wick.PLPLoadMore.toggleLoadMoreBtn();
44
+ Wick.VatToggle.reapplyDisplayClass();
45
+ })
46
+ .finally(() => {
47
+ hideLoader(Wick.PLPLoadMore.el.loader);
48
+ Wick.PLPLoadMore.el.$loadMoreBtn.blur();
49
+ Wick.BannerPlacementManager.checkProductsInColumn();
50
+ $(window).trigger('productBannerPositionChanged');
51
+ Wick.EnergyEfficiency.drawEnergyLabels();
52
+ Wick.PLP?.bindEvents();
53
+ });
54
+ },
55
+ showNewCards(newProductsHtml) {
56
+ const $newProductsHtml = $(newProductsHtml);
57
+ $(Wick.PLPLoadMore.el.productsList).append($newProductsHtml);
58
+ Wick.PackageCards.alignGridRows();
59
+ },
60
+ toggleLoadMoreBtn(checkCardsAmount = false) {
61
+ const isLastPage =
62
+ Wick.PLPLoadMore.initialPageNumber + 1 >= +Wick.PLPLoadMore.numberOfPagesPLP;
63
+ let shouldHide = isLastPage;
64
+
65
+ if (checkCardsAmount) {
66
+ const cardsCount = $(Wick.PLPLoadMore.el.productsList).children().length;
67
+ shouldHide = cardsCount <= Wick.PLPLoadMore.MAX_PRODUCTS_PER_PAGE && isLastPage;
37
68
  }
38
69
 
39
- Wick.PLPLoadMore.showNewCards(response);
40
- Wick.PLPLoadMore.toggleLoadMoreBtn();
41
- Wick.VatToggle.reapplyDisplayClass();
42
- })
43
- .finally(() => {
44
- hideLoader(Wick.PLPLoadMore.el.loader);
45
- Wick.PLPLoadMore.el.$loadMoreBtn.blur();
46
- Wick.BannerPlacementManager.checkProductsInColumn();
47
- $(window).trigger('productBannerPositionChanged');
48
- Wick.EnergyEfficiency.drawEnergyLabels();
49
- Wick.PLP?.bindEvents();
50
- })
51
- },
52
- showNewCards (newProductsHtml) {
53
- const $newProductsHtml = $(newProductsHtml);
54
- $(Wick.PLPLoadMore.el.productsList).append($newProductsHtml);
55
- },
56
- toggleLoadMoreBtn() {
57
- if (Wick.PLPLoadMore.initialPageNumber + 1 >= +Wick.PLPLoadMore.numberOfPagesPLP) {
58
- Wick.PLPLoadMore.el.$loadMoreBtn.addClass(Wick.PLPLoadMore.HIDDEN_CLASS_NAME);
59
- }
60
- },
61
- init () {
62
- if (!Wick.PLPLoadMore.el.$loadMoreBtn.length) {
63
- return;
64
- }
65
- appendLoader(Wick.PLPLoadMore.loaderPayload);
70
+ Wick.PLPLoadMore.el.$loadMoreBtn.toggleClass(
71
+ Wick.PLPLoadMore.HIDDEN_CLASS_NAME,
72
+ shouldHide
73
+ );
74
+ },
75
+ init() {
76
+ if (!Wick.PLPLoadMore.el.$loadMoreBtn.length) {
77
+ return;
78
+ }
66
79
 
67
- Wick.PLPLoadMore.el.$loadMoreBtn.on('click', Wick.PLPLoadMore.loadMore);
68
- }
69
- }
80
+ if (Wick.PLPLoadMore.el.$packageContent.length) {
81
+ Wick.PLPLoadMore.toggleLoadMoreBtn(true);
82
+ }
70
83
 
71
- $(document).ready(function () {
72
- if (!Wick.PLPLoadMore.el.$loadMoreBtn.length) {
73
- return;
74
- }
84
+ appendLoader(Wick.PLPLoadMore.loaderPayload);
85
+
86
+ Wick.PLPLoadMore.el.$loadMoreBtn.on('click', Wick.PLPLoadMore.loadMore);
87
+ },
88
+ };
75
89
 
76
- Wick.PLPLoadMore.init();
90
+ $(document).ready(function () {
91
+ Wick.PLPLoadMore.init();
77
92
  });
@@ -0,0 +1,71 @@
1
+ import { createToast } from '../utils/create-toast';
2
+ import { createLoadingButton } from '../utils/create-loading-button';
3
+ import { createEvent } from '../utils/create-event';
4
+ const notificationTemplate = require('../../../elements/notifications.hbs');
5
+
6
+ const BULK_ADD_EVENT = 'bulkAddToCart';
7
+ const QUANTITY = 1;
8
+
9
+ const bulkAddFailedResponse = {
10
+ bulkAddToCartData: {
11
+ messageType: 'error',
12
+ messageText: 'Product was not added to basket',
13
+ },
14
+ };
15
+
16
+ export function dispatchWindowEvent(eventName, payload) {
17
+ return new Promise(function (resolve, reject) {
18
+ window.dispatchEvent(createEvent(eventName, payload, { resolve, reject }));
19
+ });
20
+ }
21
+
22
+ export function createBulkAddHelper({ productCodeSelector }) {
23
+ let toast = null;
24
+ let loadingButton = null;
25
+
26
+ function getProductCode() {
27
+ return $(productCodeSelector).val();
28
+ }
29
+
30
+ function addProductToCart(postcode) {
31
+ const item = { productCode: getProductCode(), quantity: QUANTITY };
32
+
33
+ const payload = {
34
+ entries: [item]
35
+ };
36
+
37
+ if (postcode) {
38
+ payload.postCode = postcode;
39
+ }
40
+
41
+ return dispatchWindowEvent(BULK_ADD_EVENT, payload);
42
+ }
43
+
44
+ function showBulkAddResult(response) {
45
+ const bulkData = response && response.bulkAddToCartData;
46
+
47
+ if (bulkData) {
48
+ toast.show({ type: bulkData.messageType, text: bulkData.messageText });
49
+ }
50
+ }
51
+
52
+ function init() {
53
+ if (!toast) {
54
+ toast = createToast({ template: notificationTemplate });
55
+ }
56
+ if (!loadingButton) {
57
+ loadingButton = createLoadingButton();
58
+ }
59
+ }
60
+
61
+ return {
62
+ init,
63
+ getProductCode,
64
+ addProductToCart,
65
+ showBulkAddResult,
66
+ showBulkAddFailed: () => showBulkAddResult(bulkAddFailedResponse),
67
+ get loadingButton() {
68
+ return loadingButton;
69
+ },
70
+ };
71
+ }
@@ -0,0 +1,43 @@
1
+ import { createBulkAddHelper } from './bulk-add';
2
+
3
+ var Wick = window.Wick || {};
4
+
5
+ Wick.PackageBulkAdd = (function () {
6
+ const selectors = {
7
+ button: '.package-bulk-add',
8
+ productCodeInput: '.pdp-price input[name=productCodePost]',
9
+ };
10
+
11
+ const bulkAdd = createBulkAddHelper({ productCodeSelector: selectors.productCodeInput });
12
+
13
+ async function handleButtonClick(e) {
14
+ e.preventDefault();
15
+
16
+ const $buttons = $(selectors.button);
17
+
18
+ if (bulkAdd.loadingButton.isLoading($buttons)) {
19
+ return;
20
+ }
21
+
22
+ bulkAdd.loadingButton.start($buttons);
23
+
24
+ try {
25
+ bulkAdd.showBulkAddResult(await bulkAdd.addProductToCart());
26
+ Wick.MiniBasketSliderFE.isMiniBasketLoaded = false;
27
+ } catch {
28
+ bulkAdd.showBulkAddFailed();
29
+ } finally {
30
+ bulkAdd.loadingButton.stop($buttons);
31
+ }
32
+ }
33
+
34
+ function init() {
35
+ bulkAdd.init();
36
+
37
+ $(selectors.button).on('click', handleButtonClick);
38
+ }
39
+
40
+ return { init };
41
+ })();
42
+
43
+ $(document).ready(Wick.PackageBulkAdd.init);
@@ -0,0 +1,83 @@
1
+ import { isValidPostcodeField } from '../utils/validation';
2
+ import { createBulkAddHelper, dispatchWindowEvent } from './bulk-add';
3
+
4
+ var Wick = window.Wick || {};
5
+
6
+ Wick.PostcodeChecker = (function () {
7
+ const POSTCODE_CHECK_AVAILABILITY_EVENT = 'postcodeCheckAviability';
8
+ const QUANTITY = 1;
9
+
10
+ const selectors = {
11
+ root: '.postcode-checker',
12
+ input: '.postcode-checker__input',
13
+ button: '.postcode-checker__button',
14
+ productCodeInput: '.pdp-price input[name=productCodePost]',
15
+ };
16
+
17
+ const modifiers = {
18
+ hasError: 'postcode-checker--error',
19
+ };
20
+
21
+ const bulkAdd = createBulkAddHelper({ productCodeSelector: selectors.productCodeInput });
22
+
23
+ function checkPostcodeAvailability(postcode) {
24
+ const payload = { postcode, productCode: bulkAdd.getProductCode(), quantity: QUANTITY };
25
+
26
+ return dispatchWindowEvent(POSTCODE_CHECK_AVAILABILITY_EVENT, payload);
27
+ }
28
+
29
+ async function bulkAddForPostcode(postcode) {
30
+ try {
31
+ await checkPostcodeAvailability(postcode);
32
+ bulkAdd.showBulkAddResult(await bulkAdd.addProductToCart(postcode));
33
+ Wick.MiniBasketSliderFE.isMiniBasketLoaded = false;
34
+ } catch {
35
+ bulkAdd.showBulkAddFailed();
36
+ }
37
+ }
38
+
39
+ function isPostcodeValid($component, $postcodeInput) {
40
+ const isValid = isValidPostcodeField($postcodeInput.val());
41
+ $component.toggleClass(modifiers.hasError, !isValid);
42
+ console.log({ isValid, val: $postcodeInput.val() });
43
+ return isValid;
44
+ }
45
+
46
+ function handleSubmitClick($component, $postcodeInput, $submitButton) {
47
+ if (
48
+ bulkAdd.loadingButton.isLoading($submitButton) ||
49
+ !isPostcodeValid($component, $postcodeInput)
50
+ ) {
51
+ return;
52
+ }
53
+
54
+ bulkAdd.loadingButton.start($submitButton);
55
+
56
+ const postcode = $postcodeInput.val();
57
+
58
+ bulkAddForPostcode(postcode).finally(function () {
59
+ bulkAdd.loadingButton.stop($submitButton);
60
+ });
61
+ }
62
+
63
+ function init() {
64
+ bulkAdd.init();
65
+
66
+ $(selectors.root).each(function () {
67
+ const $component = $(this);
68
+ const $postcodeInput = $component.find(selectors.input);
69
+ const $submitButton = $component.find(selectors.button);
70
+
71
+ $component.removeClass(modifiers.hasError);
72
+
73
+ $submitButton.on('click', function (e) {
74
+ e.preventDefault();
75
+ handleSubmitClick($component, $postcodeInput, $submitButton);
76
+ });
77
+ });
78
+ }
79
+
80
+ return { init };
81
+ })();
82
+
83
+ $(document).ready(Wick.PostcodeChecker.init);
@@ -0,0 +1,168 @@
1
+ var Wick = window.Wick || {};
2
+
3
+ Wick.ThumbGallery = (function () {
4
+ const BASE_URL = 'https://media.wickes.co.uk/image/upload/';
5
+ const productName = window.pdpProduct && window.pdpProduct.name ? window.pdpProduct.name : '';
6
+
7
+ const IMG_BREAKPOINTS = [
8
+ { media: '(max-width: 576px)', w: 576, h: 324 },
9
+ { media: '(max-width: 768px)', w: 510, h: 287 },
10
+ { media: '(max-width: 992px)', w: 310, h: 174 },
11
+ ];
12
+
13
+ const MAIN_DEFAULT = { w: 710, h: 399 };
14
+ const THUMB = { w: 100, h: 56 };
15
+
16
+ function buildCloudinaryUrl(publicId, w, h) {
17
+ const transforms = `b_rgb:FFFFFF,c_pad,dpr_1.0,f_jpg,h_${h},q_auto:good,w_${w}`;
18
+ return `${BASE_URL}${transforms}/c_pad,h_${h},w_${w}/v1/${publicId}?pgw=1`;
19
+ }
20
+
21
+ function parseIdentifiers(hybrisString) {
22
+ return hybrisString
23
+ .trim()
24
+ .slice(1, hybrisString.length - 1)
25
+ .split(',')
26
+ .map((s) => s.trim())
27
+ .filter(Boolean);
28
+ }
29
+
30
+ function generateMainSlideHtml(publicId) {
31
+ const sources = IMG_BREAKPOINTS.map(
32
+ (bp) =>
33
+ `<source srcset="${buildCloudinaryUrl(publicId, bp.w, bp.h)}" media="${bp.media}">`
34
+ ).join('\n ');
35
+
36
+ return `<div class="thumb-gallery__slide-wrapper swiper-slide">
37
+ <picture>
38
+ ${sources}
39
+ <img class="swiper-slide-main" src="${buildCloudinaryUrl(publicId, MAIN_DEFAULT.w, MAIN_DEFAULT.h)}" alt="${productName}">
40
+ </picture>
41
+ </div>`;
42
+ }
43
+
44
+ function generateThumbSlideHtml(publicId) {
45
+ return `<div class="thumb-gallery__slide-wrapper swiper-slide">
46
+ <img class="swiper-slide-thumbs" src="${buildCloudinaryUrl(publicId, THUMB.w, THUMB.h)}" alt="${productName}">
47
+ </div>`;
48
+ }
49
+
50
+ const SELECTORS = {
51
+ galleryCarousel: '.thumb-gallery',
52
+ swiperContainerMain: '.swiper-container-main',
53
+ swiperContainerThumbs: '.swiper-container-thumbs',
54
+ swiperMainWrapper: '.swiper-container-main .swiper-wrapper',
55
+ swiperThumbsWrapper: '.swiper-container-thumbs .swiper-wrapper',
56
+ nextBtn: '.thumb-gallery__next-btn',
57
+ prevBtn: '.thumb-gallery__prev-btn',
58
+ thumbNextBtn: '.swiper-container-thumbs__next-btn',
59
+ thumbPrevBtn: '.swiper-container-thumbs__prev-btn',
60
+ swiperSlide: '.swiper-slide',
61
+ activeThumbClass: 'swiper-true-active',
62
+ };
63
+
64
+ const THUMBS_SWIPER_CONFIG = {
65
+ spaceBetween: 8,
66
+ slidesPerView: 8,
67
+ watchSlidesVisibility: true,
68
+ watchSlidesProgress: true,
69
+ watchOverflow: true,
70
+ observer: true,
71
+ observeParents: true,
72
+ simulateTouch: false,
73
+ };
74
+
75
+ const THUMBS_BREAKPOINTS = {
76
+ 991: { slidesPerView: 5 },
77
+ 767: { allowTouchMove: true, slidesPerView: 5 },
78
+ };
79
+
80
+ const MAIN_SWIPER_CONFIG = {
81
+ speed: 400,
82
+ slidesPerView: 1,
83
+ loop: true,
84
+ observer: true,
85
+ observeParents: true,
86
+ simulateTouch: false,
87
+ };
88
+
89
+ function handleThumbClick(swiper) {
90
+ return function () {
91
+ const clickedIndex = $(this).index();
92
+ swiper.slideToLoop(clickedIndex);
93
+ };
94
+ }
95
+
96
+ function updateActiveThumbnail(swiper, thumbsSwiper) {
97
+ const activeIndex = swiper.realIndex;
98
+ thumbsSwiper.slides.removeClass(SELECTORS.activeThumbClass);
99
+ thumbsSwiper.slides.eq(activeIndex).addClass(SELECTORS.activeThumbClass);
100
+ }
101
+
102
+ function getThumbsConfig($thumbNextBtn, $thumbPrevBtn) {
103
+ return {
104
+ ...THUMBS_SWIPER_CONFIG,
105
+ navigation: {
106
+ nextEl: $thumbNextBtn[0],
107
+ prevEl: $thumbPrevBtn[0],
108
+ },
109
+ breakpoints: { ...THUMBS_BREAKPOINTS },
110
+ };
111
+ }
112
+
113
+ function getMainSwiperConfig($nextBtn, $prevBtn, thumbsSwiper, onSlideChange) {
114
+ return {
115
+ ...MAIN_SWIPER_CONFIG,
116
+ navigation: {
117
+ nextEl: $nextBtn[0],
118
+ prevEl: $prevBtn[0],
119
+ },
120
+ thumbs: { swiper: thumbsSwiper },
121
+ on: { slideChange: onSlideChange },
122
+ };
123
+ }
124
+
125
+ function initializeCarousel($slider, ids) {
126
+ $slider.find(SELECTORS.swiperMainWrapper).html(ids.map(generateMainSlideHtml).join('\n'));
127
+ $slider
128
+ .find(SELECTORS.swiperThumbsWrapper)
129
+ .html(ids.map(generateThumbSlideHtml).join('\n'));
130
+
131
+ const $container = $slider.find(SELECTORS.swiperContainerMain);
132
+ const $nextBtn = $slider.find(SELECTORS.nextBtn);
133
+ const $prevBtn = $slider.find(SELECTORS.prevBtn);
134
+
135
+ const $thumbContainer = $slider.find(SELECTORS.swiperContainerThumbs);
136
+ const $thumbNextBtn = $slider.find(SELECTORS.thumbNextBtn);
137
+ const $thumbPrevBtn = $slider.find(SELECTORS.thumbPrevBtn);
138
+
139
+ const thumbsSwiper = new Swiper(
140
+ $thumbContainer[0],
141
+ getThumbsConfig($thumbNextBtn, $thumbPrevBtn)
142
+ );
143
+
144
+ const swiper = new Swiper(
145
+ $container[0],
146
+ getMainSwiperConfig($nextBtn, $prevBtn, thumbsSwiper, () => {
147
+ updateActiveThumbnail(swiper, thumbsSwiper);
148
+ })
149
+ );
150
+
151
+ $thumbContainer.on('click', SELECTORS.swiperSlide, handleThumbClick(swiper));
152
+ updateActiveThumbnail(swiper, thumbsSwiper);
153
+ }
154
+
155
+ function init(hybrisString) {
156
+ const ids = parseIdentifiers(hybrisString);
157
+
158
+ if (ids.length < 2) {
159
+ return;
160
+ }
161
+
162
+ $(SELECTORS.galleryCarousel).each(function (_, slider) {
163
+ initializeCarousel($(slider), ids);
164
+ });
165
+ }
166
+
167
+ return { init };
168
+ })();
@@ -148,7 +148,7 @@ export function validatePostcode(element, ifConvert) {
148
148
  export function isValidPostcodeField(value) {
149
149
  const transformedValue = value.toUpperCase().replaceAll(' ', '');
150
150
  const regExp = new RegExp(
151
- '^(GIR 0AA)|((([A-PR-UWYZ][0-9][0-9]?)|([A-PR-UWYZ][A-HK-Y][0-9][0-9]?)|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))[0-9][A-BD-HJLNP-UW-Z]{2})$'
151
+ '^((GIR0AA)|((([A-PR-UWYZ][0-9][0-9]?)|([A-PR-UWYZ][A-HK-Y][0-9][0-9]?)|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))[0-9][A-BD-HJLNP-UW-Z]{2}))$'
152
152
  );
153
153
  return transformedValue.replace(/\s+/g, '').length > 4 && regExp.test(transformedValue);
154
154
  }
@@ -0,0 +1,81 @@
1
+ {{#extend "base" hybrisClass="hybris-class" pageClass="products-list-page" title="Bathroom PLP" globalSearchV2="true" pagePlp=true bundle="plp" switch-vat=true}}
2
+ {{#content "head" mode="append"}}
3
+ <link type="text/css" rel="stylesheet" href="./css/components/global-search.css">
4
+ {{/content}}
5
+ {{#content "body"}}
6
+ <main>
7
+ <div class="package-plp container">
8
+ <div class="page-header page-header_border-all">
9
+ <h1 class="page-header__title">
10
+ Bathroom Suite Packages
11
+ </h1>
12
+ {{> srp-injected}}
13
+ </div>
14
+
15
+ {{> quick-filter filterData=quickFilter.iconAndText_5}}
16
+
17
+ <div class="package-plp__container">
18
+ <aside class="package-plp__search-filter">
19
+ {{> search-filter collapsed="accordion_collapsed" hidden="hidden-state"}}
20
+ </aside>
21
+
22
+ <div class="package-plp__content">
23
+ <div class="plp-filters" data-component="plp-filters" aria-label="Product filters">
24
+ <div class="plp-filters__bar plp-filters__bar-mobile" role="tablist" aria-label="Filters">
25
+ {{> kitchen/mobile-nav-item
26
+ icon="fas fa-filter"
27
+ title="Filter by"
28
+ info="24 results"
29
+ modalId="filterModal"
30
+ mod="filter-modal-cta"
31
+ }}
32
+ {{> kitchen/mobile-nav-item
33
+ icon="fas fa-sort-alt"
34
+ title="Sort by"
35
+ info="Relevance"
36
+ dropdown=true
37
+ }}
38
+ </div>
39
+ </div>
40
+
41
+ <input id="numberOfPagesPLP" value="2" type="hidden">
42
+ <div class="sort-products-list">
43
+ {{> kitchen/sort-by }}
44
+ </div>
45
+
46
+ <div class="package-plp__cards">
47
+ {{> package-card cards=ripple-plp.cards}}
48
+ {{#if search-result_v2.product-banner}}
49
+ {{#each search-result_v2.product-banner}}
50
+ {{>card_product_banner_v2}}
51
+ {{/each}}
52
+ {{/if}}
53
+ {{#if search-result_v2.bloomreach-media-banner}}
54
+ {{#each search-result_v2.bloomreach-media-banner}}
55
+ {{>card_bloomreach_media_banner}}
56
+ {{/each}}
57
+ {{/if}}
58
+ {{#if search-result_v2.sponsor-banner}}
59
+ {{#each search-result_v2.sponsor-banner}}
60
+ {{>card_sponsor_banner}}
61
+ {{/each}}
62
+ {{/if}}
63
+ </div>
64
+
65
+ <div class="load-more-wrap">
66
+ <button class="btn btn-primary btn_full btn-load-more">
67
+ Load more
68
+ </button>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </main>
74
+ {{/content}}
75
+ {{#content "foot" mode="append"}}
76
+ {{> kitchen/filter-modal isKitchenMode=false modalTitle="Filter by" }}
77
+ <script defer src="./js/search-filter.min.js"></script>
78
+ <script defer src="./js/plp-filters.min.js"></script>
79
+ <script defer src="./js/page/quick-filter.js"></script>
80
+ {{/content}}
81
+ {{/extend}}