wickes-css2 2.113.0-develop.2 → 2.113.0-develop.5
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/build/css/pdp-main-before-combine.css +1 -1
- package/build/css/pdp-main-non-critical.css +1 -1
- package/build/css/pdp-main.css +1 -1
- package/build/js/basket.min.js +1 -1
- package/build/js/bloomreach-widget.min.js +1 -1
- package/build/js/bundle.min.js +1 -1
- package/build/js/checkout.min.js +1 -1
- package/build/js/emulation.min.js +360 -3222
- package/build/js/general.bundle.min.js +1 -1
- package/build/js/merged-checkout.min.js +1 -1
- package/build/js/page/bloomreach-widget/bloomreach-recommendation-carousel-widget.js +318 -0
- package/build/js/page/bloomreach-widget/bloomreach-widget-core.js +370 -0
- package/build/js/page/bloomreach-widget/bloomreach-widget-tracking.js +16 -13
- package/build/js/page/bloomreach-widget/bloomreach-widget.js +8 -237
- package/build/js/page/bloomreach-widget/complete-your-project/cards.js +308 -0
- package/build/js/page/bloomreach-widget/complete-your-project/config.js +60 -0
- package/build/js/page/bloomreach-widget/complete-your-project/model.js +140 -0
- package/build/js/page/bloomreach-widget/complete-your-project/presenter.js +69 -0
- package/build/js/page/bloomreach-widget/complete-your-project/quantity.js +80 -0
- package/build/js/page/bloomreach-widget/complete-your-project/view.js +179 -0
- package/build/js/page/bloomreach-widget/complete-your-project/widget.js +185 -0
- package/build/js/page/bloomreach-widget/dont-forget-widget.js +15 -0
- package/build/js/page/bloomreach-widget/why-not-add-widget.js +10 -228
- package/build/js/pdp.bundle.min.js +1 -1
- package/build/js/plp.bundle.min.js +1 -1
- package/build/js/project-list.min.js +1 -1
- package/package.json +1 -1
- package/src/components/base/button.hbs +7 -0
- package/src/components/bloomreach/complete-your-project-skeleton.hbs +21 -0
- package/src/components/bloomreach/complete-your-project.hbs +6 -21
- package/src/components/bloomreach/why-not-add-card-skeleton.hbs +2 -2
- package/src/components/bloomreach/why-not-add-card.hbs +79 -60
- package/src/components/bloomreach/why-not-add-content.hbs +3 -3
- package/src/components/bloomreach/why-not-add.hbs +1 -1
- package/src/js/components/general/cart-slider.js +41 -4
- package/src/js/emulation/complete-your-project-loading.js +16 -0
- package/src/js/emulation/custom-slider-emulation.js +21 -8
- package/src/js/emulation/dont-forget-loading.js +36 -0
- package/src/js/emulation/just-added-scenarios-emulation.js +131 -0
- package/src/js/emulation/mini-basket.js +34 -34
- package/src/js/emulation/mock.js +429 -4
- package/src/js/emulation/why-not-add-loading.js +14 -3
- package/src/js/emulation/why-not-add.js +12 -14
- package/src/js/page/bloomreach-widget/bloomreach-recommendation-carousel-widget.js +318 -0
- package/src/js/page/bloomreach-widget/bloomreach-widget-core.js +370 -0
- package/src/js/page/bloomreach-widget/bloomreach-widget-tracking.js +16 -13
- package/src/js/page/bloomreach-widget/bloomreach-widget.js +8 -237
- package/src/js/page/bloomreach-widget/complete-your-project/cards.js +308 -0
- package/src/js/page/bloomreach-widget/complete-your-project/config.js +60 -0
- package/src/js/page/bloomreach-widget/complete-your-project/model.js +140 -0
- package/src/js/page/bloomreach-widget/complete-your-project/presenter.js +69 -0
- package/src/js/page/bloomreach-widget/complete-your-project/quantity.js +80 -0
- package/src/js/page/bloomreach-widget/complete-your-project/view.js +179 -0
- package/src/js/page/bloomreach-widget/complete-your-project/widget.js +185 -0
- package/src/js/page/bloomreach-widget/dont-forget-widget.js +15 -0
- package/src/js/page/bloomreach-widget/why-not-add-widget.js +10 -228
- package/src/page_product-details-with-global-search-v2.html +4 -6
- package/src/page_product-details-with-why-not-add-single.html +1 -1
- package/src/scss/components/bloomreach/_bloomreach.scss +1 -0
- package/src/scss/components/bloomreach/_card-shared.scss +24 -0
- package/src/scss/components/bloomreach/_complete-card.scss +1 -9
- package/src/scss/components/bloomreach/_why-not-add-card.scss +137 -10
- package/src/scss/components/bloomreach/_why-not-add.scss +31 -2
- package/build/js/page/bloomreach-widget/complete-your-project-widget.js +0 -1100
- package/src/js/page/bloomreach-widget/complete-your-project-widget.js +0 -1100
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { COMPLETE_YOUR_PROJECT_EL as EL } from './config';
|
|
2
|
+
|
|
3
|
+
export function createCompleteYourProjectModel() {
|
|
4
|
+
let recommendations = [];
|
|
5
|
+
|
|
6
|
+
function setRecommendations(payloadData) {
|
|
7
|
+
recommendations = Wick.BloomreachWidget.normalizePayload(payloadData);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function getRecommendations() {
|
|
11
|
+
return recommendations;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getRecommendationIndex($card) {
|
|
15
|
+
return Number($card.attr(EL.recommendationIndexAttr));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getRecommendation($card) {
|
|
19
|
+
return recommendations[getRecommendationIndex($card)];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function findVariantProduct(recommendation, selectedValue) {
|
|
23
|
+
if (
|
|
24
|
+
!recommendation ||
|
|
25
|
+
!recommendation.variantProducts ||
|
|
26
|
+
!recommendation.variantProducts.length
|
|
27
|
+
) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return recommendation.variantProducts.find(function (variantProduct) {
|
|
32
|
+
return `${variantProduct.code}` === `${selectedValue}`;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getCardQuantity($card) {
|
|
37
|
+
const quantity = parseInt($card.find(EL.quantityInput).val(), 10);
|
|
38
|
+
|
|
39
|
+
return Number.isNaN(quantity) ? 1 : quantity;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getCardProduct($card) {
|
|
43
|
+
const recommendation = getRecommendation($card);
|
|
44
|
+
|
|
45
|
+
if (!recommendation) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const $dropdown = $card.find(EL.dropdownRoot);
|
|
50
|
+
const selectedValue = $dropdown.length ? $dropdown.data(EL.selectedValueData) : '';
|
|
51
|
+
|
|
52
|
+
if (selectedValue) {
|
|
53
|
+
return findVariantProduct(recommendation, selectedValue) || recommendation.baseProduct;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return recommendation.baseProduct;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getSelectedItems($root) {
|
|
60
|
+
const items = [];
|
|
61
|
+
|
|
62
|
+
$root.find(EL.completeCard).each(function () {
|
|
63
|
+
const $card = $(this);
|
|
64
|
+
|
|
65
|
+
if (!$card.find(EL.cardCheckbox).prop('checked')) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const product = getCardProduct($card);
|
|
70
|
+
|
|
71
|
+
if (!product) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const recommendationIndex = getRecommendationIndex($card);
|
|
76
|
+
const recommendation = recommendations[recommendationIndex];
|
|
77
|
+
|
|
78
|
+
items.push({
|
|
79
|
+
recommendationIndex,
|
|
80
|
+
baseProduct: recommendation && recommendation.baseProduct,
|
|
81
|
+
product,
|
|
82
|
+
quantity: getCardQuantity($card),
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return items;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function toSelectedEntries(items) {
|
|
90
|
+
return items.map(function (item) {
|
|
91
|
+
return {
|
|
92
|
+
product: item.product,
|
|
93
|
+
quantity: item.quantity,
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function toAddToCartEntries(items) {
|
|
99
|
+
return items.map(function (item) {
|
|
100
|
+
return {
|
|
101
|
+
productCode: item.product.code,
|
|
102
|
+
quantity: item.quantity,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function toTrackingItems(items) {
|
|
108
|
+
return items
|
|
109
|
+
.filter(function (item) {
|
|
110
|
+
return item.recommendationIndex !== 0;
|
|
111
|
+
})
|
|
112
|
+
.map(function (item) {
|
|
113
|
+
if (
|
|
114
|
+
!item.baseProduct ||
|
|
115
|
+
!item.baseProduct.code ||
|
|
116
|
+
!item.product ||
|
|
117
|
+
!item.product.code
|
|
118
|
+
) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
item_id: item.baseProduct.code,
|
|
124
|
+
sku: item.product.code,
|
|
125
|
+
};
|
|
126
|
+
})
|
|
127
|
+
.filter(Boolean);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
setRecommendations,
|
|
132
|
+
getRecommendations,
|
|
133
|
+
getRecommendationIndex,
|
|
134
|
+
findVariantProduct,
|
|
135
|
+
getSelectedItems,
|
|
136
|
+
toSelectedEntries,
|
|
137
|
+
toAddToCartEntries,
|
|
138
|
+
toTrackingItems,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export function createCompleteYourProjectPresenter() {
|
|
2
|
+
function getDropdownOptions(product) {
|
|
3
|
+
if (!product.variantOptions || !product.variantOptions.length) {
|
|
4
|
+
return [];
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
return product.variantOptions.map(function (variantOption) {
|
|
8
|
+
const qualifiers = variantOption.variantOptionQualifiers || [];
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
label: qualifiers
|
|
12
|
+
.map(function (qualifier) {
|
|
13
|
+
return qualifier.value;
|
|
14
|
+
})
|
|
15
|
+
.join(', '),
|
|
16
|
+
value: variantOption.code,
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getSelectedDropdownLabel(options, selectedValue) {
|
|
22
|
+
const selectedOption = options.find(function (option) {
|
|
23
|
+
return option.value === selectedValue;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return selectedOption ? selectedOption.label : '';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getProductRenderData(product, index, options = {}) {
|
|
30
|
+
const shouldShowDropdown = index !== 0;
|
|
31
|
+
const dropdownOptions = shouldShowDropdown ? getDropdownOptions(product) : [];
|
|
32
|
+
const selectedDropdownValue = options.selectedDropdownValue || '';
|
|
33
|
+
const selectedDropdownLabel = getSelectedDropdownLabel(
|
|
34
|
+
dropdownOptions,
|
|
35
|
+
selectedDropdownValue
|
|
36
|
+
);
|
|
37
|
+
const renderData = Wick.BloomreachWidget.getProductRenderData(product, {
|
|
38
|
+
image: options.image,
|
|
39
|
+
fallbackProduct: options.fallbackProduct,
|
|
40
|
+
fallbackExcVat: true,
|
|
41
|
+
});
|
|
42
|
+
const showFromPrice = Boolean(
|
|
43
|
+
index !== 0 &&
|
|
44
|
+
!selectedDropdownValue &&
|
|
45
|
+
renderData.price &&
|
|
46
|
+
renderData.price.priceType === 'FROM'
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
...renderData,
|
|
51
|
+
showFromPrice,
|
|
52
|
+
dropdownOptions: dropdownOptions.map(function (option) {
|
|
53
|
+
return {
|
|
54
|
+
...option,
|
|
55
|
+
selected: option.value === selectedDropdownValue,
|
|
56
|
+
};
|
|
57
|
+
}),
|
|
58
|
+
checkboxId: `${product.code}-${index}`,
|
|
59
|
+
dropdownError: options.dropdownError || false,
|
|
60
|
+
checked: options.checked || false,
|
|
61
|
+
selectedDropdownValue,
|
|
62
|
+
selectedDropdownLabel,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
getProductRenderData,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createCountStepper } from '../../utils/create-count-stepper';
|
|
2
|
+
import { COMPLETE_YOUR_PROJECT_EL as EL } from './config';
|
|
3
|
+
|
|
4
|
+
export function createCompleteYourProjectQuantity({ validateCardDropdown, calculateTotal }) {
|
|
5
|
+
function resetCardQuantity($card) {
|
|
6
|
+
$card
|
|
7
|
+
.find(EL.quantityInput)
|
|
8
|
+
.val(1)
|
|
9
|
+
.data(EL.previousQuantityData, 1)
|
|
10
|
+
.removeData(EL.quantityReadyData)
|
|
11
|
+
.removeData(EL.countStepperInitializedData);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function initQuantityField($root, inputSel) {
|
|
15
|
+
const stepper = createCountStepper({
|
|
16
|
+
inputSel,
|
|
17
|
+
min: 1,
|
|
18
|
+
onChange(qty, inputEl) {
|
|
19
|
+
const $input = $(inputEl);
|
|
20
|
+
const $card = $input.closest(EL.completeCard);
|
|
21
|
+
const $completeWidget = $input.closest(EL.completeWidget);
|
|
22
|
+
const $checkbox = $card.find(EL.cardCheckbox);
|
|
23
|
+
const previousQuantity = $input.data(EL.previousQuantityData) || 1;
|
|
24
|
+
|
|
25
|
+
if (!$input.data(EL.quantityReadyData)) {
|
|
26
|
+
$input.data(EL.previousQuantityData, qty || 1);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!validateCardDropdown($card)) {
|
|
31
|
+
$input.val(previousQuantity);
|
|
32
|
+
|
|
33
|
+
if (previousQuantity <= 1) {
|
|
34
|
+
$card.find(EL.countMinusBtn).prop('disabled', true);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
$checkbox.prop('checked', true);
|
|
41
|
+
$card.addClass(EL.selectedClass);
|
|
42
|
+
$input.data(EL.previousQuantityData, qty);
|
|
43
|
+
$input.trigger('change');
|
|
44
|
+
|
|
45
|
+
if ($completeWidget.length) {
|
|
46
|
+
calculateTotal($completeWidget);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
stepper.init($root);
|
|
52
|
+
$root.find(inputSel).data(EL.quantityReadyData, true);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function initQuantityFields($root) {
|
|
56
|
+
$root.find(EL.quantityInput).each(function () {
|
|
57
|
+
const $input = $(this);
|
|
58
|
+
|
|
59
|
+
if ($input.data(EL.countStepperInitializedData)) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const inputId = $input.attr('id');
|
|
64
|
+
|
|
65
|
+
if (!inputId) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
$input.data(EL.countStepperInitializedData, true);
|
|
70
|
+
$input.data(EL.previousQuantityData, parseInt($input.val(), 10) || 1);
|
|
71
|
+
|
|
72
|
+
initQuantityField($input.closest(EL.countStepperRoot), `#${inputId}`);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
resetCardQuantity,
|
|
78
|
+
initQuantityFields,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import {
|
|
2
|
+
COMPLETE_YOUR_PROJECT_EL as EL,
|
|
3
|
+
COMPLETE_YOUR_PROJECT_TEMPLATES as TEMPLATES,
|
|
4
|
+
} from './config';
|
|
5
|
+
|
|
6
|
+
export function createCompleteYourProjectView(model, presenter) {
|
|
7
|
+
function getCtaText(selectedCount) {
|
|
8
|
+
if (!selectedCount) {
|
|
9
|
+
return 'Add product(s) to basket';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return `Add ${selectedCount} product${selectedCount > 1 ? 's' : ''} to basket`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function setCtaText($button, text) {
|
|
16
|
+
const $text = $button.find(Wick.BloomreachWidget.el.loadingButtonText);
|
|
17
|
+
|
|
18
|
+
if ($text.length) {
|
|
19
|
+
$text.text(text);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
$button.text(text);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function renderWidget($container) {
|
|
27
|
+
const $content = $container.children(EL.widgetContent).first().length
|
|
28
|
+
? $container.children(EL.widgetContent).first()
|
|
29
|
+
: $container.find(EL.widgetContent).first();
|
|
30
|
+
const recommendations = model.getRecommendations();
|
|
31
|
+
|
|
32
|
+
if (!$content.length || !recommendations.length) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
$content.html(TEMPLATES.wrapper());
|
|
37
|
+
|
|
38
|
+
const $wrapper = $content.find(EL.widgetWrapper);
|
|
39
|
+
|
|
40
|
+
recommendations.forEach(function (recommendation, index) {
|
|
41
|
+
const product = presenter.getProductRenderData(recommendation.baseProduct, index);
|
|
42
|
+
|
|
43
|
+
$wrapper.append(TEMPLATES.card(product));
|
|
44
|
+
$wrapper.children(EL.completeCard).last().attr(EL.recommendationIndexAttr, index);
|
|
45
|
+
|
|
46
|
+
if (index === 0 && recommendations.length > 1) {
|
|
47
|
+
$wrapper.append(TEMPLATES.divider());
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const isSwitchVat = !!(window.ACC && window.ACC.app && window.ACC.app.isVatToggleAvailable);
|
|
52
|
+
|
|
53
|
+
$content.append(TEMPLATES.summary({ 'switch-vat': isSwitchVat }));
|
|
54
|
+
$container.show();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function updateSummary($root, response = {}) {
|
|
58
|
+
const totalPriceExclusiveVat = response.totalPriceExclusiveVat || response.totalExcVatPrice;
|
|
59
|
+
const totalWasPriceExclusiveVat =
|
|
60
|
+
response.totalWasPriceExclusiveVat || response.totalExcVatWasPrice;
|
|
61
|
+
const { vatInc, vatExc } = Wick.BloomreachWidget.el;
|
|
62
|
+
const $price = $root.find(EL.summaryPriceValue);
|
|
63
|
+
const $salePrice = $root.find(EL.summarySalePrice);
|
|
64
|
+
const $total = $root.find(EL.summaryTotal);
|
|
65
|
+
|
|
66
|
+
if (!$price.length) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (response.totalWasPrice) {
|
|
71
|
+
$total.addClass('complete-widget__total-sale');
|
|
72
|
+
|
|
73
|
+
const $priceInc = $price.find(vatInc);
|
|
74
|
+
|
|
75
|
+
if ($priceInc.length) {
|
|
76
|
+
$priceInc.text(response.totalWasPrice);
|
|
77
|
+
$price.find(vatExc).text(totalWasPriceExclusiveVat || response.totalWasPrice);
|
|
78
|
+
$salePrice.find(vatInc).text(response.totalPrice || '');
|
|
79
|
+
$salePrice.find(vatExc).text(totalPriceExclusiveVat || response.totalPrice || '');
|
|
80
|
+
} else {
|
|
81
|
+
$price.text(response.totalWasPrice);
|
|
82
|
+
$salePrice.text(response.totalPrice || '');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
$salePrice.show();
|
|
86
|
+
Wick.BloomreachWidget.reapplyVatDisplay();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
$total.removeClass('complete-widget__total-sale');
|
|
91
|
+
|
|
92
|
+
const $priceInc = $price.find(vatInc);
|
|
93
|
+
|
|
94
|
+
if ($priceInc.length) {
|
|
95
|
+
$priceInc.text(response.totalPrice || '£0.00');
|
|
96
|
+
$price.find(vatExc).text(totalPriceExclusiveVat || response.totalPrice || '£0.00');
|
|
97
|
+
$salePrice.find(vatInc).text('');
|
|
98
|
+
$salePrice.find(vatExc).text('');
|
|
99
|
+
$salePrice.hide();
|
|
100
|
+
} else {
|
|
101
|
+
$price.text(response.totalPrice || '£0.00');
|
|
102
|
+
$salePrice.text('').hide();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
Wick.BloomreachWidget.reapplyVatDisplay();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function updateCta($root) {
|
|
109
|
+
const selectedCount = $root.find(EL.cardCheckbox).filter(':checked').length;
|
|
110
|
+
const $cta = $root.find(EL.ctaButton);
|
|
111
|
+
|
|
112
|
+
if (!$cta.length) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
$cta.prop('disabled', !selectedCount);
|
|
117
|
+
setCtaText($cta, getCtaText(selectedCount));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function setInitialSummary($root) {
|
|
121
|
+
const firstItem = model.getSelectedItems($root)[0];
|
|
122
|
+
|
|
123
|
+
if (!firstItem || !firstItem.product) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const product = firstItem.product;
|
|
128
|
+
const displayPrice = Wick.BloomreachWidget.getDisplayPrice(product);
|
|
129
|
+
const priceExcVat = Wick.BloomreachWidget.getDisplayPriceExcVat(product);
|
|
130
|
+
const wasPriceFormatted = Wick.BloomreachWidget.getWasPriceFormatted(product);
|
|
131
|
+
|
|
132
|
+
updateSummary($root, {
|
|
133
|
+
totalPrice: Wick.BloomreachWidget.getPriceFormattedValue(displayPrice) || '£0.00',
|
|
134
|
+
totalWasPrice: wasPriceFormatted || null,
|
|
135
|
+
totalPriceExclusiveVat: Wick.BloomreachWidget.getPriceFormattedValue(priceExcVat),
|
|
136
|
+
totalWasPriceExclusiveVat: Wick.BloomreachWidget.getExcVatWasPrice(product) || null,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function alignBlock(selector, $root) {
|
|
141
|
+
const $els = $root.find(selector);
|
|
142
|
+
|
|
143
|
+
$els.css('min-height', '');
|
|
144
|
+
|
|
145
|
+
if (!$els.length || Wick.Responsive.getCurrentBreakpoint() !== 'up-lg') {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let maxHeight = 0;
|
|
150
|
+
|
|
151
|
+
$els.each(function () {
|
|
152
|
+
maxHeight = Math.max(maxHeight, $(this).height());
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
if (maxHeight > 0) {
|
|
156
|
+
$els.css('min-height', maxHeight + 'px');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function alignCardBlocks($root) {
|
|
161
|
+
alignBlock(EL.titleEl, $root);
|
|
162
|
+
alignBlock(EL.optionsEl, $root);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function resetWidgetState($root) {
|
|
166
|
+
$root.find(EL.cardCheckbox).prop('checked', false);
|
|
167
|
+
$root.find(EL.completeCard).removeClass(EL.selectedClass);
|
|
168
|
+
$root.find(EL.quantityInput).val(1).data(EL.previousQuantityData, 1);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
renderWidget,
|
|
173
|
+
updateSummary,
|
|
174
|
+
updateCta,
|
|
175
|
+
setInitialSummary,
|
|
176
|
+
alignCardBlocks,
|
|
177
|
+
resetWidgetState,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
var Wick = window.Wick || {};
|
|
2
|
+
|
|
3
|
+
import { createLoadingButton } from '../../utils/create-loading-button';
|
|
4
|
+
import { createToast } from '../../utils/create-toast';
|
|
5
|
+
import { createBloomreachWidget } from '../bloomreach-widget-core';
|
|
6
|
+
import { createBloomreachWidgetTracking } from '../bloomreach-widget-tracking';
|
|
7
|
+
import {
|
|
8
|
+
COMPLETE_YOUR_PROJECT_EL as EL,
|
|
9
|
+
COMPLETE_YOUR_PROJECT_EVENTS as EVENTS,
|
|
10
|
+
COMPLETE_YOUR_PROJECT_TEMPLATES as TEMPLATES,
|
|
11
|
+
} from './config';
|
|
12
|
+
import { createCompleteYourProjectModel } from './model';
|
|
13
|
+
import { createCompleteYourProjectPresenter } from './presenter';
|
|
14
|
+
import { createCompleteYourProjectView } from './view';
|
|
15
|
+
import { createCompleteYourProjectCards } from './cards';
|
|
16
|
+
|
|
17
|
+
const model = createCompleteYourProjectModel();
|
|
18
|
+
const presenter = createCompleteYourProjectPresenter();
|
|
19
|
+
const view = createCompleteYourProjectView(model, presenter);
|
|
20
|
+
const tracking = createBloomreachWidgetTracking();
|
|
21
|
+
|
|
22
|
+
let loadingButton = null;
|
|
23
|
+
let toast = null;
|
|
24
|
+
let cards = null;
|
|
25
|
+
|
|
26
|
+
function ensureServices() {
|
|
27
|
+
if (!toast) {
|
|
28
|
+
toast = createToast({
|
|
29
|
+
template: TEMPLATES.notification,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!loadingButton) {
|
|
34
|
+
loadingButton = createLoadingButton();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function handleBulkAddToCartResponse(response) {
|
|
39
|
+
const bulkData = response && response.bulkAddToCartData;
|
|
40
|
+
|
|
41
|
+
if (!bulkData) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
toast.show({
|
|
46
|
+
type: bulkData.messageType,
|
|
47
|
+
text: bulkData.messageText,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function dispatchCalculateTotal($root) {
|
|
52
|
+
view.updateCta($root);
|
|
53
|
+
|
|
54
|
+
const selectedItems = model.getSelectedItems($root);
|
|
55
|
+
|
|
56
|
+
return Wick.BloomreachWidget.dispatchWidgetEvent(EVENTS.calculateTotal, {
|
|
57
|
+
entries: model.toSelectedEntries(selectedItems),
|
|
58
|
+
}).then(function (response) {
|
|
59
|
+
view.updateSummary($root, response);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function dispatchAddToCart($root, $button, selectedItems) {
|
|
64
|
+
loadingButton.start($button);
|
|
65
|
+
|
|
66
|
+
return Wick.BloomreachWidget.dispatchWidgetEvent(EVENTS.addToCart, {
|
|
67
|
+
entries: model.toAddToCartEntries(selectedItems),
|
|
68
|
+
})
|
|
69
|
+
.then(function (response) {
|
|
70
|
+
handleBulkAddToCartResponse(response);
|
|
71
|
+
|
|
72
|
+
if (Wick.MiniBasketSliderFE) {
|
|
73
|
+
Wick.MiniBasketSliderFE.isMiniBasketLoaded = false;
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
.catch(function () {
|
|
77
|
+
handleBulkAddToCartResponse({
|
|
78
|
+
bulkAddToCartData: {
|
|
79
|
+
messageType: 'error',
|
|
80
|
+
messageText: 'Selected product(s) were not added to basket',
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
})
|
|
84
|
+
.finally(function () {
|
|
85
|
+
loadingButton.stop($button);
|
|
86
|
+
view.updateCta($root);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function bindAddToCart($root) {
|
|
91
|
+
$root.off('click.bloomreachAddToCart', EL.ctaButton);
|
|
92
|
+
$root.on('click.bloomreachAddToCart', EL.ctaButton, function (event) {
|
|
93
|
+
event.preventDefault();
|
|
94
|
+
|
|
95
|
+
const $button = $(this);
|
|
96
|
+
|
|
97
|
+
if ($button.prop('disabled') || loadingButton.isLoading($button)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const selectedItems = model.getSelectedItems($root);
|
|
102
|
+
const trackingItems = model.toTrackingItems(selectedItems);
|
|
103
|
+
|
|
104
|
+
if (trackingItems.length) {
|
|
105
|
+
tracking.trackAddToCart(trackingItems);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
dispatchAddToCart($root, $button, selectedItems);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function bindVatToggle() {
|
|
113
|
+
if (Wick.BloomreachWidget.bindVatToggle) {
|
|
114
|
+
Wick.BloomreachWidget.bindVatToggle('completeYourProjectVatToggle');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function initRenderedWidget($container) {
|
|
119
|
+
ensureServices();
|
|
120
|
+
|
|
121
|
+
const $completeWidget = $container.find(EL.completeWidget).first();
|
|
122
|
+
|
|
123
|
+
if (!$completeWidget.length) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
Wick.BloomreachWidget.removeBlankTargets($completeWidget);
|
|
128
|
+
Wick.BloomreachWidget.drawRating($completeWidget);
|
|
129
|
+
cards.bindCardSelection($completeWidget);
|
|
130
|
+
cards.bindDropdowns();
|
|
131
|
+
cards.bindDropdownValidation($completeWidget);
|
|
132
|
+
bindAddToCart($completeWidget);
|
|
133
|
+
cards.bindProductTracking($completeWidget);
|
|
134
|
+
bindVatToggle();
|
|
135
|
+
cards.initQuantityFields($completeWidget);
|
|
136
|
+
|
|
137
|
+
$completeWidget.find(EL.dropdownRoot).removeClass(EL.dropdownErrorClass);
|
|
138
|
+
|
|
139
|
+
view.alignCardBlocks($completeWidget);
|
|
140
|
+
view.updateCta($completeWidget);
|
|
141
|
+
view.setInitialSummary($completeWidget);
|
|
142
|
+
Wick.BloomreachWidget.reapplyVatDisplay();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
cards = createCompleteYourProjectCards({
|
|
146
|
+
model,
|
|
147
|
+
presenter,
|
|
148
|
+
view,
|
|
149
|
+
tracking,
|
|
150
|
+
calculateTotal: dispatchCalculateTotal,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const Widget = createBloomreachWidget({
|
|
154
|
+
el: EL,
|
|
155
|
+
tracking,
|
|
156
|
+
setPayload(payloadData) {
|
|
157
|
+
model.setRecommendations(payloadData);
|
|
158
|
+
},
|
|
159
|
+
renderWidget($container) {
|
|
160
|
+
cards.resetDropdownState();
|
|
161
|
+
view.renderWidget($container);
|
|
162
|
+
},
|
|
163
|
+
initRenderedWidget,
|
|
164
|
+
getViewTargets($containers) {
|
|
165
|
+
return [$containers.find(EL.titleEl).get(0), $containers.find(EL.ctaButton).get(-1)];
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
$(document).ready(function () {
|
|
170
|
+
Wick.Responsive.onResize(function () {
|
|
171
|
+
$(EL.widgetContainer).each(function () {
|
|
172
|
+
const $completeWidget = $(this).find(EL.completeWidget);
|
|
173
|
+
|
|
174
|
+
if ($completeWidget.length) {
|
|
175
|
+
view.alignCardBlocks($completeWidget);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
window.addEventListener('pagehide', function () {
|
|
182
|
+
cards.resetBackForwardState();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
export default Widget;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createBloomreachRecommendationCarouselWidget } from './bloomreach-recommendation-carousel-widget';
|
|
2
|
+
|
|
3
|
+
const DontForgetWidget = createBloomreachRecommendationCarouselWidget({
|
|
4
|
+
namespace: 'dontForget',
|
|
5
|
+
title: 'Don’t forget',
|
|
6
|
+
modifier: 'why-not-add--dont-forget',
|
|
7
|
+
widgetContainer: '.custom-slider.just-added .custom-slider__wrap',
|
|
8
|
+
appendToContainer: true,
|
|
9
|
+
doNotShowAddedProductPopup: true,
|
|
10
|
+
disableAfterSuccess: true,
|
|
11
|
+
disableAfterFailure: true,
|
|
12
|
+
addToCartError: 'Product has not been added to basket',
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export default DontForgetWidget;
|