wickes-css2 2.117.0-develop.3 → 2.117.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.
- package/Readme.md +0 -1
- package/build/css/category-main.css +1 -1
- package/build/css/components/checkout-payment-details-v2.css +1 -1
- package/build/css/homepage-main.css +1 -1
- package/build/css/kitchen-plp-main.css +1 -1
- package/build/css/main.css +1 -1
- package/build/css/my-account-main-v2.css +1 -1
- package/build/css/my-account-main.css +1 -1
- package/build/css/pages/checkout-new.css +1 -1
- package/build/css/pages/checkout.css +1 -1
- package/build/css/pages/page_my-order.css +1 -1
- package/build/css/pages/page_wismo-details.css +1 -1
- package/build/css/pdp-main-before-combine.css +1 -1
- package/build/css/pdp-main-critical.css +1 -1
- package/build/css/pdp-main-non-critical.css +1 -1
- package/build/css/pdp-main.css +1 -1
- package/build/css/plp-main.css +1 -1
- package/build/css/store-locator-main.css +1 -1
- package/build/img/payment/checkout/giftcard.svg +28 -0
- package/build/img/payment/footer/giftcard.svg +28 -0
- package/build/js/account-members.min.js +1 -1
- package/build/js/add-project-list-id.min.js +1 -1
- package/build/js/address-book.min.js +1 -1
- package/build/js/basket.min.js +2 -2
- package/build/js/bundle.min.js +1 -1
- package/build/js/change-password.min.js +1 -1
- package/build/js/checkout.min.js +2 -2
- package/build/js/emulation.min.js +424 -82
- package/build/js/general.bundle.min.js +1 -1
- package/build/js/gift-cards.min.js +1 -1
- package/build/js/merged-checkout.min.js +2 -2
- package/build/js/page/bloomreach-widget/bloomreach-widget-core.js +1 -3
- package/build/js/page/checkout-payment-details.js +114 -10
- package/build/js/page/components/gift-cards.js +524 -115
- package/build/js/page/components/postcode-lookup/postcode-lookup-api.js +56 -0
- package/build/js/page/components/postcode-lookup/postcode-lookup-render.js +98 -0
- package/build/js/page/components/postcode-lookup/postcode-lookup-validation.js +81 -0
- package/build/js/page/components/postcode-lookup.js +503 -0
- package/build/js/page/ripple/bulk-add.js +2 -2
- package/build/js/page/ripple/thumb-gallery.js +14 -8
- package/build/js/page/utils/address-utils.js +32 -0
- package/build/js/page/utils/validation.js +54 -1
- package/build/js/pdp.bundle.min.js +2 -2
- package/build/js/personal-details.min.js +1 -1
- package/build/js/plp.bundle.min.js +1 -1
- package/build/js/postcode-checker.min.js +1 -1
- package/build/js/project-list.min.js +57 -2
- package/build/js/quiz.min.js +1 -1
- package/build/js/track-my-order.min.js +1 -1
- package/package.json +5 -1
- package/src/components/checkout-payment-details-v2.hbs +1 -0
- package/src/components/checkout_order-summary-new.hbs +6 -0
- package/src/components/checkout_payment-new.hbs +35 -8
- package/src/components/gift-cards.hbs +8 -15
- package/src/components/order-address.hbs +28 -0
- package/src/components/payments.hbs +7 -6
- package/src/components/postcode-lookup-v2.hbs +85 -0
- package/src/components/wismo-giftcard-payment-item.hbs +29 -0
- package/src/components/wismo-payment.hbs +10 -0
- package/src/data/data_checkout-giftcards.json +7 -0
- package/src/data/data_delivery-address-v2.json +4 -0
- package/src/data/data_payments-checkout.json +4 -0
- package/src/data/data_postcode-lookup.json +200 -0
- package/src/data/data_wismo.json +46 -1
- package/src/data/footer_menu.json +4 -0
- package/src/elements/input.hbs +3 -1
- package/src/img/payment/checkout/giftcard.svg +28 -0
- package/src/img/payment/footer/giftcard.svg +28 -0
- package/src/js/components/general/footer.js +63 -56
- package/src/js/emulation/checkout-payment-details.js +2 -0
- package/src/js/emulation/gift-cards.js +22 -0
- package/src/js/emulation/mock.js +21 -20
- package/src/js/emulation/postcode-checker.js +1 -1
- package/src/js/emulation/postcode-lookup.js +122 -0
- package/src/js/page/bloomreach-widget/bloomreach-widget-core.js +1 -3
- package/src/js/page/checkout-payment-details.js +114 -10
- package/src/js/page/components/gift-cards.js +524 -115
- package/src/js/page/components/postcode-lookup/postcode-lookup-api.js +56 -0
- package/src/js/page/components/postcode-lookup/postcode-lookup-render.js +98 -0
- package/src/js/page/components/postcode-lookup/postcode-lookup-validation.js +81 -0
- package/src/js/page/components/postcode-lookup.js +503 -0
- package/src/js/page/ripple/bulk-add.js +2 -2
- package/src/js/page/ripple/thumb-gallery.js +14 -8
- package/src/js/page/utils/address-utils.js +32 -0
- package/src/js/page/utils/validation.js +54 -1
- package/src/page_checkout_confirmation-gift-card-split-payment.html +339 -0
- package/src/page_checkout_confirmation-gift-card.html +339 -0
- package/src/page_my_account_payment_info_gift_cards.html +96 -0
- package/src/page_my_account_payment_info_gift_cards_split_payment.html +96 -0
- package/src/page_product-details-billie.html +2 -0
- package/src/page_product-details-clearpay.html +1 -0
- package/src/scss/common/_CTAs.scss +4 -0
- package/src/scss/components/_gift-cards.scss +66 -9
- package/src/scss/components/_payments-checkout.scss +2 -2
- package/src/scss/components/_payments-v2.scss +5 -7
- package/src/scss/components/_postcode-lookup-v2.scss +164 -0
- package/src/scss/components/checkout-payment-details-v2.scss +1 -0
- package/src/scss/helpers/_CTAs.scss +26 -0
- package/src/scss/helpers/_variables.scss +2 -0
- package/src/scss/pages/_checkout-confirmation-new.scss +96 -3
- package/src/scss/pages/page_wismo-details.scss +29 -0
- package/src/sitemap.html +24 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { resolvePostcodeToAddress } from '../../utils/address-utils';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_OPTIONS = {
|
|
4
|
+
apiKey: 'ak_ksfw10yaf8TFYw3IA6alHPLQatQsY',
|
|
5
|
+
baseUrl: 'https://api.ideal-postcodes.co.uk/v1',
|
|
6
|
+
country: 'GBR',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function createPostcodeLookupApi(options = {}) {
|
|
10
|
+
const { apiKey, baseUrl, country } = { ...DEFAULT_OPTIONS, ...options };
|
|
11
|
+
|
|
12
|
+
const requests = {
|
|
13
|
+
async checkKey() {
|
|
14
|
+
const res = await fetch(`${baseUrl}/keys/${apiKey}`);
|
|
15
|
+
if (!res.ok) throw new Error(`Key check failed with status ${res.status}`);
|
|
16
|
+
|
|
17
|
+
const data = await res.json();
|
|
18
|
+
return { available: !!data.result?.available };
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
async autocomplete(query) {
|
|
22
|
+
const params = new URLSearchParams({
|
|
23
|
+
api_key: apiKey,
|
|
24
|
+
query,
|
|
25
|
+
context: country,
|
|
26
|
+
});
|
|
27
|
+
const res = await fetch(`${baseUrl}/autocomplete/addresses?${params}`);
|
|
28
|
+
if (!res.ok) throw new Error(`Autocomplete failed with status ${res.status}`);
|
|
29
|
+
|
|
30
|
+
const data = await res.json();
|
|
31
|
+
return data.result?.hits || [];
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
async resolve(suggestion) {
|
|
35
|
+
const id = encodeURIComponent(suggestion.id);
|
|
36
|
+
const res = await fetch(
|
|
37
|
+
`${baseUrl}/autocomplete/addresses/${id}/${country.toLowerCase()}?api_key=${apiKey}`
|
|
38
|
+
);
|
|
39
|
+
if (!res.ok) throw new Error(`Resolve failed with status ${res.status}`);
|
|
40
|
+
|
|
41
|
+
const data = await res.json();
|
|
42
|
+
return data.result || null;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
Object.assign(requests, (window.Wick && window.Wick.PostcodeLookupApi) || {});
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
checkKey: () => requests.checkKey(),
|
|
50
|
+
autocomplete: (query) => requests.autocomplete(query),
|
|
51
|
+
async resolve(suggestion) {
|
|
52
|
+
const result = await requests.resolve(suggestion);
|
|
53
|
+
return result ? resolvePostcodeToAddress(result) : null;
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export const MODES = {
|
|
2
|
+
LOOKUP: 'lookup',
|
|
3
|
+
MANUAL: 'manual',
|
|
4
|
+
UNAVAILABLE: 'unavailable',
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const classes = {
|
|
8
|
+
item: 'address-suggestion',
|
|
9
|
+
highlighted: 'is-highlighted',
|
|
10
|
+
match: 'text-match',
|
|
11
|
+
hidden: 'd-none',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const MANUAL_PLACEHOLDERS = {
|
|
15
|
+
line1: 'Type address line 1',
|
|
16
|
+
line2: 'Type address line 2',
|
|
17
|
+
town: 'Type town/city',
|
|
18
|
+
postcode: 'Type postcode',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function renderSuggestionParts(text, query) {
|
|
22
|
+
const index = query ? text.toLowerCase().indexOf(query.toLowerCase()) : -1;
|
|
23
|
+
if (index === -1) return [$('<span>', { text })];
|
|
24
|
+
|
|
25
|
+
return [
|
|
26
|
+
{ text: text.slice(0, index), isMatch: false },
|
|
27
|
+
{ text: text.slice(index, index + query.length), isMatch: true },
|
|
28
|
+
{ text: text.slice(index + query.length), isMatch: false },
|
|
29
|
+
]
|
|
30
|
+
.filter((part) => part.text)
|
|
31
|
+
.map((part) => $('<span>', { text: part.text }).toggleClass(classes.match, part.isMatch));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function renderDropdown(lookup) {
|
|
35
|
+
const { state, $search, $dropdown, $hint, $manual, $list } = lookup;
|
|
36
|
+
|
|
37
|
+
$dropdown.toggleClass(classes.hidden, !state.isOpen);
|
|
38
|
+
if (!state.isOpen) return;
|
|
39
|
+
|
|
40
|
+
const isEmptyQuery = !$search.val();
|
|
41
|
+
|
|
42
|
+
$hint.toggleClass(classes.hidden, !isEmptyQuery);
|
|
43
|
+
$manual.toggleClass(classes.hidden, isEmptyQuery);
|
|
44
|
+
$list.find('.' + classes.item).remove();
|
|
45
|
+
|
|
46
|
+
if (isEmptyQuery) return;
|
|
47
|
+
|
|
48
|
+
const query = $search.val().trim();
|
|
49
|
+
const $items = state.suggestions.map((item, index) =>
|
|
50
|
+
$('<li>', {
|
|
51
|
+
class: classes.item,
|
|
52
|
+
role: 'option',
|
|
53
|
+
tabindex: -1,
|
|
54
|
+
'data-index': index,
|
|
55
|
+
})
|
|
56
|
+
.append(renderSuggestionParts(item.suggestion, query))
|
|
57
|
+
.toggleClass(classes.highlighted, index === state.highlightedIndex)
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
$manual.before($items);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function renderHighlight(lookup) {
|
|
64
|
+
const { state, $list } = lookup;
|
|
65
|
+
|
|
66
|
+
$list.find('.' + classes.item).each(function () {
|
|
67
|
+
$(this).toggleClass(classes.highlighted, $(this).data('index') === state.highlightedIndex);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function renderMode(lookup) {
|
|
72
|
+
const { state, $searchWrap, $expand } = lookup;
|
|
73
|
+
|
|
74
|
+
$searchWrap.toggleClass(classes.hidden, state.mode !== MODES.LOOKUP);
|
|
75
|
+
$expand.toggleClass(classes.hidden, state.mode !== MODES.MANUAL);
|
|
76
|
+
autoGrow(lookup);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function toggleManualPlaceholders(lookup, isShown) {
|
|
80
|
+
const { $fields } = lookup;
|
|
81
|
+
|
|
82
|
+
Object.keys(MANUAL_PLACEHOLDERS).forEach((key) => {
|
|
83
|
+
$fields[key].attr('placeholder', isShown ? MANUAL_PLACEHOLDERS[key] : '');
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function autoGrow(lookup) {
|
|
88
|
+
const { $search } = lookup;
|
|
89
|
+
|
|
90
|
+
if (!$search.is(':visible')) return;
|
|
91
|
+
|
|
92
|
+
const el = $search[0];
|
|
93
|
+
const { placeholder } = el;
|
|
94
|
+
el.placeholder = '';
|
|
95
|
+
el.style.height = 'auto';
|
|
96
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
97
|
+
el.placeholder = placeholder;
|
|
98
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isAntiXssValid,
|
|
3
|
+
isElementInViewport,
|
|
4
|
+
isFieldRowVisible,
|
|
5
|
+
isValidLookupPostcode,
|
|
6
|
+
updateStylingErrorForElement,
|
|
7
|
+
validateFieldByRule,
|
|
8
|
+
} from '../../utils/validation';
|
|
9
|
+
import errorMessages from '../../utils/errorMesages';
|
|
10
|
+
import { scrollToElement } from '../../utils/helpers';
|
|
11
|
+
import { toCanonicalPostcode } from '../../utils/address-utils';
|
|
12
|
+
|
|
13
|
+
const SCROLL_OFFSET = 100;
|
|
14
|
+
const FORM_ROW_SELECTOR = '.form-row';
|
|
15
|
+
|
|
16
|
+
export const ADDRESS_FIELDS = ['line1', 'line2', 'town', 'postcode'];
|
|
17
|
+
|
|
18
|
+
const isPostcodeValid = (value) => isValidLookupPostcode(toCanonicalPostcode(value));
|
|
19
|
+
|
|
20
|
+
const fieldRules = {
|
|
21
|
+
line1: {
|
|
22
|
+
required: true,
|
|
23
|
+
validate: isAntiXssValid,
|
|
24
|
+
message: errorMessages.errorAddressLine1,
|
|
25
|
+
},
|
|
26
|
+
line2: {
|
|
27
|
+
required: false,
|
|
28
|
+
validate: isAntiXssValid,
|
|
29
|
+
message: errorMessages.errorAddressLine2,
|
|
30
|
+
},
|
|
31
|
+
town: {
|
|
32
|
+
required: true,
|
|
33
|
+
validate: isAntiXssValid,
|
|
34
|
+
message: errorMessages.errorTown,
|
|
35
|
+
},
|
|
36
|
+
postcode: {
|
|
37
|
+
required: true,
|
|
38
|
+
validate: isPostcodeValid,
|
|
39
|
+
message: errorMessages.errorPostcode,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export function validateField(lookup, key) {
|
|
44
|
+
const { $fields } = lookup;
|
|
45
|
+
|
|
46
|
+
return validateFieldByRule($fields[key], fieldRules[key]);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function validateSearch(lookup) {
|
|
50
|
+
const { state, $search, $fields } = lookup;
|
|
51
|
+
|
|
52
|
+
if (!isFieldRowVisible($search)) return true;
|
|
53
|
+
|
|
54
|
+
const hasAddressFields = ADDRESS_FIELDS.some((key) => $fields[key].val());
|
|
55
|
+
const isValid = !!$search.val() && (state.isOpen || hasAddressFields);
|
|
56
|
+
|
|
57
|
+
updateStylingErrorForElement($search, isValid, errorMessages.errorAddress);
|
|
58
|
+
return isValid;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function validateAddressInputs(lookup) {
|
|
62
|
+
ADDRESS_FIELDS.forEach((key) => validateField(lookup, key));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function validate(lookup, { shouldScroll = true } = {}) {
|
|
66
|
+
const { $search, $fields } = lookup;
|
|
67
|
+
const checks = [
|
|
68
|
+
{ $field: $search, isValid: validateSearch(lookup) },
|
|
69
|
+
...ADDRESS_FIELDS.map((key) => ({
|
|
70
|
+
$field: $fields[key],
|
|
71
|
+
isValid: validateField(lookup, key),
|
|
72
|
+
})),
|
|
73
|
+
];
|
|
74
|
+
const firstInvalid = checks.find((check) => !check.isValid);
|
|
75
|
+
|
|
76
|
+
if (firstInvalid && shouldScroll) {
|
|
77
|
+
const $row = firstInvalid.$field.closest(FORM_ROW_SELECTOR);
|
|
78
|
+
if (!isElementInViewport($row)) scrollToElement($row, SCROLL_OFFSET);
|
|
79
|
+
}
|
|
80
|
+
return !firstInvalid;
|
|
81
|
+
}
|