@nakedwines/naked-components 1.0.0 → 8.642.3

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.

Potentially problematic release.


This version of @nakedwines/naked-components might be problematic. Click here for more details.

Files changed (121) hide show
  1. package/README.md +33 -0
  2. package/build-utils/update-library.js +91 -0
  3. package/library/globals.js +4 -0
  4. package/library/index.js +69 -0
  5. package/package.json +22 -6
  6. package/src/components/badges/Badge.vue +20 -0
  7. package/src/components/badges/Badge.vue?1b45 +1 -0
  8. package/src/components/badges/Badge.vue?5424 +10 -0
  9. package/src/components/badges/Badge.vue?c5b6 +1 -0
  10. package/src/components/banners/Banner.vue +20 -0
  11. package/src/components/banners/Banner.vue?2006 +1 -0
  12. package/src/components/banners/Banner.vue?36d1 +1 -0
  13. package/src/components/banners/Banner.vue?9b97 +4 -0
  14. package/src/components/buttons/Button.vue +21 -0
  15. package/src/components/buttons/Button.vue?2035 +1 -0
  16. package/src/components/buttons/Button.vue?5c96 +1 -0
  17. package/src/components/buttons/Button.vue?838e +26 -0
  18. package/src/components/buttons/Button.vue?e88c +1 -0
  19. package/src/components/buttons/LoadingButton.vue +20 -0
  20. package/src/components/buttons/LoadingButton.vue?2f5e +17 -0
  21. package/src/components/buttons/LoadingButton.vue?4a65 +1 -0
  22. package/src/components/buttons/LoadingButton.vue?65be +1 -0
  23. package/src/components/buttons/Ripple.vue +20 -0
  24. package/src/components/buttons/Ripple.vue?130a +1 -0
  25. package/src/components/buttons/Ripple.vue?2026 +13 -0
  26. package/src/components/buttons/Ripple.vue?4835 +1 -0
  27. package/src/components/cards/ContentCard.vue +20 -0
  28. package/src/components/cards/ContentCard.vue?35c8 +10 -0
  29. package/src/components/cards/ContentCard.vue?7164 +1 -0
  30. package/src/components/cards/ContentCard.vue?ec15 +1 -0
  31. package/src/components/cards/bottle-cards/CaseContentsCard.vue +20 -0
  32. package/src/components/cards/bottle-cards/CaseContentsCard.vue?3ac7 +1 -0
  33. package/src/components/cards/bottle-cards/CaseContentsCard.vue?7e00 +4 -0
  34. package/src/components/cards/bottle-cards/CaseContentsCard.vue?dd6f +1 -0
  35. package/src/components/cards/bottle-cards/CaseProductCard.vue +21 -0
  36. package/src/components/cards/bottle-cards/CaseProductCard.vue?0cb0 +1 -0
  37. package/src/components/cards/bottle-cards/CaseProductCard.vue?1bd2 +1 -0
  38. package/src/components/cards/bottle-cards/CaseProductCard.vue?25e9 +4 -0
  39. package/src/components/cards/bottle-cards/CaseProductCard.vue?95f9 +1 -0
  40. package/src/components/cards/bottle-cards/WineBottleCard.vue +21 -0
  41. package/src/components/cards/bottle-cards/WineBottleCard.vue?61a8 +1 -0
  42. package/src/components/cards/bottle-cards/WineBottleCard.vue?7e9a +1 -0
  43. package/src/components/cards/bottle-cards/WineBottleCard.vue?bd3e +4 -0
  44. package/src/components/cards/bottle-cards/WineBottleCard.vue?bdcc +1 -0
  45. package/src/components/cards/bottle-cards/components/BiaText.vue +20 -0
  46. package/src/components/cards/bottle-cards/components/BiaText.vue?123e +1 -0
  47. package/src/components/cards/bottle-cards/components/BiaText.vue?3e10 +1 -0
  48. package/src/components/cards/bottle-cards/components/BiaText.vue?d135 +4 -0
  49. package/src/components/cards/bottle-cards/components/HeartRatingPanel.vue +20 -0
  50. package/src/components/cards/bottle-cards/components/HeartRatingPanel.vue?712f +4 -0
  51. package/src/components/cards/bottle-cards/components/HeartRatingPanel.vue?c55a +1 -0
  52. package/src/components/cards/bottle-cards/components/HeartRatingPanel.vue?ee3b +1 -0
  53. package/src/components/cards/bottle-cards/components/PriceBreakdownPanel.vue +20 -0
  54. package/src/components/cards/bottle-cards/components/PriceBreakdownPanel.vue?5052 +1 -0
  55. package/src/components/cards/bottle-cards/components/PriceBreakdownPanel.vue?5838 +4 -0
  56. package/src/components/cards/bottle-cards/components/PriceBreakdownPanel.vue?7aad +1 -0
  57. package/src/components/cards/bottle-cards/components/WineDetailPanel.vue +20 -0
  58. package/src/components/cards/bottle-cards/components/WineDetailPanel.vue?5047 +1 -0
  59. package/src/components/cards/bottle-cards/components/WineDetailPanel.vue?8e3b +1 -0
  60. package/src/components/cards/bottle-cards/components/WineDetailPanel.vue?d1ea +4 -0
  61. package/src/components/carousel/Carousel.vue +21 -0
  62. package/src/components/carousel/Carousel.vue?492f +1 -0
  63. package/src/components/carousel/Carousel.vue?4e80 +4 -0
  64. package/src/components/carousel/Carousel.vue?66a0 +1 -0
  65. package/src/components/carousel/Carousel.vue?72ce +1 -0
  66. package/src/components/chips/Chip.vue +20 -0
  67. package/src/components/chips/Chip.vue?7e2c +1 -0
  68. package/src/components/chips/Chip.vue?9563 +4 -0
  69. package/src/components/chips/Chip.vue?f42c +1 -0
  70. package/src/components/footers/sticky-footer/StickyFooter.vue +20 -0
  71. package/src/components/footers/sticky-footer/StickyFooter.vue?10bf +4 -0
  72. package/src/components/footers/sticky-footer/StickyFooter.vue?b195 +1 -0
  73. package/src/components/footers/sticky-footer/StickyFooter.vue?e2d9 +1 -0
  74. package/src/components/forms/CheckboxInput.vue +20 -0
  75. package/src/components/forms/CheckboxInput.vue?1713 +1 -0
  76. package/src/components/forms/CheckboxInput.vue?51c9 +1 -0
  77. package/src/components/forms/CheckboxInput.vue?feea +4 -0
  78. package/src/components/forms/QuantityInput.vue +20 -0
  79. package/src/components/forms/QuantityInput.vue?233a +25 -0
  80. package/src/components/forms/QuantityInput.vue?4975 +1 -0
  81. package/src/components/forms/QuantityInput.vue?bb30 +1 -0
  82. package/src/components/forms/SelectInput.vue +172 -0
  83. package/src/components/forms/SelectInput.vue?1d47 +1 -0
  84. package/src/components/forms/SelectInput.vue?642a +21 -0
  85. package/src/components/forms/SelectInput.vue?7590 +20 -0
  86. package/src/components/forms/SelectInput.vue?f210 +1 -0
  87. package/src/components/forms/SelectInput.vue?fc78 +1 -0
  88. package/src/components/icons/CustomisableHeart.vue +19 -0
  89. package/src/components/icons/CustomisableHeart.vue?30ab +1 -0
  90. package/src/components/icons/CustomisableHeart.vue?ce76 +4 -0
  91. package/src/components/icons/Icon.vue +21 -0
  92. package/src/components/icons/Icon.vue?47ee +9 -0
  93. package/src/components/icons/Icon.vue?6e26 +1 -0
  94. package/src/components/icons/Icon.vue?897e +1 -0
  95. package/src/components/icons/Icon.vue?e753 +1 -0
  96. package/src/components/modal/ProductDetailModal.vue +20 -0
  97. package/src/components/modal/ProductDetailModal.vue?5d3a +1 -0
  98. package/src/components/modal/ProductDetailModal.vue?9f0f +1 -0
  99. package/src/components/modal/ProductDetailModal.vue?a2a9 +4 -0
  100. package/src/components/popover/Popover.vue +20 -0
  101. package/src/components/popover/Popover.vue?088e +1 -0
  102. package/src/components/popover/Popover.vue?4dad +1 -0
  103. package/src/components/popover/Popover.vue?7034 +7 -0
  104. package/src/components/roundels/Roundel.vue +20 -0
  105. package/src/components/roundels/Roundel.vue?14bf +7 -0
  106. package/src/components/roundels/Roundel.vue?a97a +1 -0
  107. package/src/components/roundels/Roundel.vue?aa28 +1 -0
  108. package/src/components/shelf/Shelf.vue +20 -0
  109. package/src/components/shelf/Shelf.vue?50f3 +1 -0
  110. package/src/components/shelf/Shelf.vue?9eba +1 -0
  111. package/src/components/shelf/Shelf.vue?d8e7 +4 -0
  112. package/src/globals/assortments.js +80 -0
  113. package/src/globals/csrf.js +25 -0
  114. package/src/globals/functions.js +166 -0
  115. package/src/globals/products.js +251 -0
  116. package/src/globals/responsive.js +53 -0
  117. package/src/globals/validation.js +8 -0
  118. package/src/globals/variables.js +48 -0
  119. package/src/mixins/productCard.js +151 -0
  120. package/src/styles/js-modules/breakpoints.scss +2 -0
  121. package/index.js +0 -0
@@ -0,0 +1,251 @@
1
+ /* eslint-disable no-prototype-builtins */
2
+
3
+ import { csrf } from './csrf';
4
+ import { Assortments } from './assortments';
5
+ import { Logger } from './functions';
6
+ import { styleNamesIds, styleColours } from './variables';
7
+ import 'whatwg-fetch';
8
+
9
+ export const Products = {
10
+
11
+ /**
12
+ * Fetches a list of products
13
+ * @param {Array} productIds the list of product IDs
14
+ * @returns {Array} returns an array of products
15
+ */
16
+ getProductsById({ productIds }) {
17
+ return new Promise((resolve, reject) => {
18
+ if (!productIds) {
19
+ reject({ error: 'productId is required' });
20
+ return;
21
+ }
22
+
23
+ fetch(`/products?productIds=${productIds}`, {
24
+ 'method': 'GET'
25
+ }).then(response => {
26
+ return resolve(response.json());
27
+ }).catch(error => reject({ error: error }));
28
+ });
29
+ },
30
+
31
+ /**
32
+ * Adds a product to basket
33
+ * @param {Array} productId the product ID to add to basket
34
+ * @param {Number} quantity quantity to add to basket
35
+ * @returns {Object} returns a success/error response
36
+ */
37
+ addToBasket({ productId, quantity = 1 }) {
38
+ return new Promise((resolve, reject) => {
39
+ if (!productId) {
40
+ reject({ error: 'productId is required' });
41
+ return;
42
+ }
43
+
44
+ const headers = new Headers(csrf.header);
45
+ const formData = new FormData();
46
+ formData.append('productId', productId.toString());
47
+ formData.append('quantity', quantity.toString());
48
+
49
+ fetch('/customer/add-to-cart.json', {
50
+ 'method': 'POST',
51
+ 'headers': headers,
52
+ 'body': formData
53
+ }).then(response => {
54
+ return resolve(response.json());
55
+ }).catch(error => reject({ error: error }));
56
+ });
57
+ },
58
+
59
+ /**
60
+ * Displays an add to basket notification in the header
61
+ * @param {String} productName the product name to display
62
+ */
63
+ showATBConfirmation(productName) {
64
+ if (window && window.Notify && window.Notify.CoinPurse) {
65
+ const config = {
66
+ settings: { purseType: 'product-added' },
67
+ productName: productName,
68
+ autoDismiss: true,
69
+ timeout: 4000
70
+ };
71
+
72
+ window.Notify.CoinPurse.show(config.settings, config.productName, config.autoDismiss, config.timeout);
73
+
74
+ if (window.nkd && window.nkd.headerCart) {
75
+ window.nkd.headerCart.reload();
76
+ }
77
+ }
78
+ },
79
+
80
+ _parseProduct(data) {
81
+ let model = null;
82
+ let type;
83
+ let imageAssortmentKey;
84
+ let imageMediumCutout = 'mediumCutout';
85
+
86
+ // skip item if it's not in the right format
87
+ if (!data || !data.object) { Logger.log('_parseProduct skipping item', "'object' property not found"); return null; }
88
+
89
+ // wrap in try catch so we can skip an item if the data is inconsistent
90
+ try {
91
+ // use different keys if it's a case rather than a single product
92
+ if (data && data.object && data.object.productTypeDesc && data.object.productTypeDesc == 'Case') {
93
+ type = 'case-product';
94
+ imageAssortmentKey = 'headline';
95
+ } else {
96
+ type = 'single-product';
97
+ imageAssortmentKey = 'background';
98
+ }
99
+
100
+ model = {
101
+ id: data.object.id,
102
+ type: type,
103
+ data: {
104
+ id: data.object.id,
105
+ heading: data.object.productName,
106
+ subHeading: null,
107
+ thumbnail: '/merchandising/content/wines/default-content/background.jpg',
108
+ button: null,
109
+ pricesCurrent: {
110
+ prices: {}
111
+ },
112
+ positiveRatingPercentage: null,
113
+ numberOfRatings: null,
114
+ angelOnly: data.object.angelOnly,
115
+ tickpoints: null,
116
+ tickpointsCase: null,
117
+ taste: null,
118
+ originForSpiritsOrBeer: data.object.originForSpiritsOrBeer,
119
+ style: {},
120
+ percentageMatch: null,
121
+ likeThis: null,
122
+ producer: {},
123
+ url: null,
124
+ productTypeDesc: null,
125
+ productQuantity: null,
126
+ scheme: {},
127
+ assortmentObjects: {},
128
+ origin: '',
129
+ wineGrape: '',
130
+ hideFromView: false,
131
+ hideRatings: false,
132
+ specialDelivery: false,
133
+ freeShipping: false,
134
+ bia: {},
135
+ vegan: false,
136
+ vegetarian: false,
137
+ alcoholStrength: null,
138
+ bottleSizeDesc: '',
139
+ promotionalPrice: null,
140
+ angelPrices: false
141
+ }
142
+ };
143
+ // attach ratings
144
+ if (data.object.hasOwnProperty('ratingData')) {
145
+ model.data.positiveRatingPercentage = data.object.ratingData.positiveRatingPercentage;
146
+ model.data.numberOfRatings = data.object.ratingData.numberOfRatings;
147
+ model.data.hideRatings = data.object.ratingData.hideRatings;
148
+ }
149
+ // attach pricing
150
+ if (data.object.pricesCurrent && data.object.pricesCurrent.prices) {
151
+ model.data.pricesCurrent.prices = data.object.pricesCurrent.prices;
152
+ // attach ATB button (customer price)
153
+ if (data.object.pricesCurrent.prices.customerPrice) { model.data.button = data.object.pricesCurrent.prices.customerPrice; }
154
+ }
155
+ if (data.object.assortmentObjects) {
156
+ // attach thumbnail image
157
+ let thumbnail = Assortments._getAssortmentObject(data.object.assortmentObjects, imageAssortmentKey);
158
+ if (thumbnail) model.data.thumbnail = thumbnail;
159
+ // attach bottleImage
160
+ let bottleImage = Assortments._getAssortmentObject(data.object.assortmentObjects, imageMediumCutout);
161
+ if (bottleImage) model.data.bottleImage = bottleImage;
162
+ // attach tickpoints
163
+ let tickpoints = Assortments._getAssortmentObject(data.object.assortmentObjects, 'whatWeThink');
164
+ if (tickpoints) model.data.tickpoints = tickpoints;
165
+ let tickpointsCase = Assortments._getAssortmentObject(data.object.assortmentObjects, 'whatWeSay');
166
+ if (tickpointsCase) model.data.tickpointsCase = tickpointsCase;
167
+ }
168
+ // attach style data
169
+ if (data.object.taste) {
170
+ model.data.style = this._getWineStyleByName(data.object.taste);
171
+ // attach sub style data (modern/classic)
172
+ if (data.object.productSubStyle) { model.data.style.subStyle = data.object.productSubStyle.toLowerCase(); }
173
+ }
174
+ // attach producer data
175
+ if (data.object.producer) {
176
+ model.data.producer.firstName = data.object.producer.firstName;
177
+ model.data.producer.lastName = data.object.producer.lastName;
178
+ model.data.producer.url = data.object.producer.url;
179
+ model.data.producer.urlString = data.object.producer.urlString;
180
+ }
181
+ // attach url
182
+ if (data.object.url) { model.data.url = data.object.url; }
183
+ // attach percentage match and like this
184
+ if (data.object.customerProductLikeThis) {
185
+ let likeData = data.object.customerProductLikeThis;
186
+
187
+ if (likeData.hasOwnProperty('likeThis')) { model.data.likeThis = likeData.likeThis; }
188
+
189
+ if (likeData.custProdRecommendation && likeData.custProdRecommendation.hasOwnProperty('score')) {
190
+ model.data.percentageMatch = likeData.custProdRecommendation.score;
191
+ const percVal = likeData.custProdRecommendation.score;
192
+ let formatted = (typeof percVal !== 'number') ? percVal : `${(percVal * 100).toFixed(0)}%`;
193
+ model.data.percentageMatchFormatted = formatted;
194
+ model.data.subHeading = formatted + ' Match';
195
+ }
196
+ }
197
+ // attach type description
198
+ if (data.object.productTypeDesc) { model.data.productTypeDesc = data.object.productTypeDesc; }
199
+ // attach product quantity
200
+ if (data.object.productQuantity) { model.data.productQuantity = data.object.productQuantity; }
201
+ // attached bottle quantity
202
+ if(data.object.quantity) { model.data.quantity = data.object.quantity; }
203
+ // attach scheme
204
+ if (data.object.scheme && data.object.scheme.id) { model.data.scheme = data.object.scheme; }
205
+ // attach assortment objects
206
+ if (data.object.assortmentObjects && data.object.assortmentObjects.objects && data.object.assortmentObjects.objects.length > 0) {
207
+ data.object.assortmentObjects.objects.forEach(ao => {
208
+ model.data.assortmentObjects[ao.name] = ao;
209
+ });
210
+ }
211
+ // attach shipping data
212
+ if (data.object.hasOwnProperty('shipAsCase')) { model.data.shipAsCase = data.object.shipAsCase; }
213
+ if (data.object.hasOwnProperty('packingSlots')) { model.data.packingSlots = data.object.packingSlots; }
214
+ // attach more info
215
+ if (data.object.hasOwnProperty('origin')) { model.data.origin = data.object.origin; }
216
+ if (data.object.hasOwnProperty('taste')) { model.data.taste = data.object.taste; }
217
+ if (data.object.hasOwnProperty('wineGrape')) { model.data.wineGrape = data.object.wineGrape; }
218
+ if (data.object.hasOwnProperty('hideFromView')) { model.data.hideFromView = data.object.hideFromView; }
219
+ if (data.object.hasOwnProperty('specialDelivery')) { model.data.specialDelivery = data.object.specialDelivery; }
220
+ if (data.object.hasOwnProperty('freeShipping')) { model.data.freeShipping = data.object.freeShipping; }
221
+ if (data.object.productRatingBreakdownList && data.object.productRatingBreakdownList.length > 0) { model.data.bia = data.object.productRatingBreakdownList[0]; }
222
+ if (data.object.hasOwnProperty('vegan')) { model.data.vegan = data.object.vegan; }
223
+ if (data.object.hasOwnProperty('vegetarian')) { model.data.vegetarian = data.object.vegetarian; }
224
+ if (data.object.hasOwnProperty('alcoholStrength')) { model.data.alcoholStrength = data.object.alcoholStrength; }
225
+ if (data.object.hasOwnProperty('bottleSizeDesc')) { model.data.bottleSizeDesc = data.object.bottleSizeDesc; }
226
+ if (data.object.hasOwnProperty('averageRating')) { model.data.averageRating = data.object.averageRating; }
227
+ if (data.object.hasOwnProperty('region')) { model.data.region = data.object.region; }
228
+ // for free bottles
229
+ if(data.promotionalPrice !== null && data.promotionalPrice === 0) { model.data.promotionalPrice = data.promotionalPrice; }
230
+ if(data.angelPrices !== null) { model.data.angelPrices = data.angelPrices; }
231
+ }
232
+ catch(error) { console.error('_parseProduct skipping item', error); return null; }
233
+ return model;
234
+ },
235
+
236
+ // get the wine style from data prop
237
+ _getWineStyleByName(styleName) {
238
+ let result = {};
239
+ if (!styleName) return result;
240
+ if (styleNamesIds[styleName]) {
241
+ let styleId = styleNamesIds[styleName];
242
+ let colours = styleColours[styleId];
243
+ result = {
244
+ name: styleName,
245
+ id: styleId,
246
+ colours: colours
247
+ };
248
+ }
249
+ return result;
250
+ },
251
+ };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Method used for creating the computed breakpoint objects
3
+ * for use.
4
+ * @param {[Object, Number]} propToUse - the prop to use for creating the object
5
+ * @param {Object} defaults - default settings to use
6
+ * @return {Object} - containing breakpoints and values
7
+ */
8
+ export function getResponsiveOption(propToUse, defaults) {
9
+ if (propToUse && typeof propToUse === 'object') {
10
+ let obj = {};
11
+ for (let index = 0; index < Object.keys(defaults).length; index++) {
12
+ const breakpointProp = Object.keys(defaults)[index];
13
+ const breakpointPropValue = propToUse[breakpointProp];
14
+ // if propToUse declares a breakpoint, apply to this breakpoint and up
15
+ if (breakpointPropValue || (typeof breakpointPropValue === 'number' && breakpointPropValue === 0)) {
16
+ for (let remaining = index; remaining < Object.keys(defaults).length; remaining++) {
17
+ obj[Object.keys(defaults)[remaining]] = breakpointPropValue;
18
+ }
19
+ }
20
+ // fallback if not created yet, uses defaults equivalent value
21
+ else if (!obj[breakpointProp]) {
22
+ obj[breakpointProp] = defaults[breakpointProp];
23
+ }
24
+ }
25
+ return obj;
26
+ }
27
+ else if (propToUse && typeof propToUse === 'number') {
28
+ // Number defined, apply to all breakpoints
29
+ let obj = {};
30
+ for (let index = 0; index < Object.keys(defaults).length; index++) {
31
+ const breakpointProp = Object.keys(defaults)[index];
32
+ obj[breakpointProp] = propToUse;
33
+ }
34
+ return obj;
35
+ }
36
+ else {
37
+ // if responsive prop not defined, just use defaults
38
+ return defaults;
39
+ }
40
+ }
41
+
42
+ import { breakpoints } from './variables.js';
43
+ export function getCurrentBreakpoint() {
44
+ let ret;
45
+ for (let index = 0; index < Object.keys(breakpoints).length; index++) {
46
+ const breakProp = Object.keys(breakpoints)[index];
47
+ if (window.innerWidth < breakpoints[breakProp]) {
48
+ ret = (index === 0) ? 'xs' : Object.keys(breakpoints)[index-1];
49
+ break;
50
+ }
51
+ }
52
+ return ret ? ret : 'xl';
53
+ }
@@ -0,0 +1,8 @@
1
+ export function getValidationMessage(element, options) {
2
+ const defaults = {
3
+ fallback: 'Input not valid, please try something else'
4
+ };
5
+ const opt = Object.assign({}, defaults, options);
6
+
7
+ return element.validationMessage != null ? element.validationMessage : opt.fallback;
8
+ }
@@ -0,0 +1,48 @@
1
+ import sassBreakpoints from '../styles/js-modules/breakpoints.scss';
2
+
3
+ export const breakpoints = {
4
+ xs: parseInt(sassBreakpoints.breakpointXs), // mobile min (iphone 5/se)
5
+ sm: parseInt(sassBreakpoints.breakpointSm), // large mobile
6
+ md: parseInt(sassBreakpoints.breakpointMd), // tablet
7
+ lg: parseInt(sassBreakpoints.breakpointLg), // desktop
8
+ xl: parseInt(sassBreakpoints.breakpointXl), // wide
9
+ };
10
+
11
+ export const styleNamesIds = {
12
+ 'Crisp White': 'WHITE_CRISP',
13
+ 'Fruity White': 'WHITE_FRUITY',
14
+ 'Rich White': 'WHITE_RICH',
15
+ 'Sweet White': 'WHITE_SWEET',
16
+ 'Fruity Red': 'RED_FRUITY',
17
+ 'Smooth Red': 'RED_SMOOTH',
18
+ 'Big Red': 'RED_BIG',
19
+ 'Rose': 'ROSE',
20
+ 'Sparkling': 'SPARKLING',
21
+ 'Dessert & Fortified': 'DESSERT_FORTIFIED'
22
+ };
23
+
24
+ export const styleIdsNames = {
25
+ WHITE_CRISP: 'Crisp White',
26
+ WHITE_FRUITY: 'Fruity White',
27
+ WHITE_RICH: 'Rich White',
28
+ WHITE_SWEET: 'Sweet White',
29
+ RED_FRUITY: 'Fruity Red',
30
+ RED_SMOOTH: 'Smooth Red',
31
+ RED_BIG: 'Big Red',
32
+ ROSE: 'Rosé',
33
+ SPARKLING: 'Sparkling',
34
+ DESSERT_FORTIFIED: 'Dessert & Fortified'
35
+ };
36
+
37
+ export const styleColours = {
38
+ WHITE_CRISP: { primary: '#CCD402', secondary: '#BAC106' },
39
+ WHITE_FRUITY: { primary: '#5A8C24', secondary: '#4F7A17' },
40
+ WHITE_RICH: { primary: '#E8BC02', secondary: '#D4AC04' },
41
+ WHITE_SWEET: { primary: '#01A6B4', secondary: '#068F9A' },
42
+ RED_FRUITY: { primary: '#AC0F63', secondary: '#8E0C51' },
43
+ RED_SMOOTH: { primary: '#E4481D', secondary: '#CF3D15' },
44
+ RED_BIG: { primary: '#552681', secondary: '#451B6D' },
45
+ ROSE: { primary: '#E86D83', secondary: '#DC6378' },
46
+ SPARKLING: { primary: '#AC8A4D', secondary: '#9C7C43' },
47
+ DESSERT_FORTIFIED: { primary: '#151432', secondary: '#06061C' },
48
+ };
@@ -0,0 +1,151 @@
1
+ import { convertStyleCodeToClassName } from '../globals/functions';
2
+ import { Products } from '../globals/products.js';
3
+ const bottleShotPlaceHolderPath = '/merchandising/content/placeholders/wine-bottle-placeholder.png';
4
+
5
+ const productCard = {
6
+ props: {
7
+ product: {
8
+ type: Object,
9
+ required: false
10
+ },
11
+ recommendationType: {
12
+ type: String,
13
+ required: false,
14
+ default: 'bia'
15
+ },
16
+ styleBar: {
17
+ type: Boolean,
18
+ required: false,
19
+ default: false
20
+ },
21
+ type: {
22
+ type: String,
23
+ required: false
24
+ }
25
+ },
26
+
27
+ computed: {
28
+ productData() {
29
+ let product = this.product;
30
+
31
+ if(product && product.data) {
32
+ return product.data
33
+ } else {
34
+ return null;
35
+ }
36
+ },
37
+
38
+ typeBia() {
39
+ return this.recommendationType === 'bia' &&
40
+ this.productData.bia &&
41
+ this.productData.bia.positiveRatingPercentage;
42
+ },
43
+
44
+ typePercentagematch() {
45
+ return this.recommendationType === 'percentageMatch' &&
46
+ this.productData.percentageMatchFormatted;
47
+ },
48
+
49
+ percentageMatchNumber() {
50
+ let score = null,
51
+ productData = this.productData;
52
+
53
+ if(
54
+ productData.customerProductLikeThis &&
55
+ productData.customerProductLikeThis.custProdRecommendation &&
56
+ productData.customerProductLikeThis.custProdRecommendation.score
57
+ ) {
58
+ score = productData.customerProductLikeThis.custProdRecommendation.score;
59
+ score * 100;
60
+ }
61
+
62
+ return score;
63
+ },
64
+
65
+ itemPriceString() { return `${this.currencySymbol == '&#36;' ? '$' : '£'}${this.productData.pricesCurrent.prices.customerPrice.toFixed(2)}` },
66
+
67
+ productImage() {
68
+ if (this.productData.bottleImage) { return window.staticImageUrl + this.productData.bottleImage; }
69
+ else {
70
+ let find = false;
71
+
72
+ if (this.productData.assortmentObjects.objects) {
73
+ find = this.productData.assortmentObjects.objects.findIndex(item => item.name == "mediumCutout");
74
+ }
75
+
76
+ if(find) {
77
+ return window.staticImageUrl + this.productData.assortmentObjects.objects[find].contentPath;
78
+ } else {
79
+ return window.staticImageUrl + bottleShotPlaceHolderPath;
80
+ }
81
+ }
82
+ },
83
+
84
+ caseImage() {
85
+ // TODO: Tidy up - maybe include default placeholder image here if not available?
86
+ if (this.productData.bottleImage) { return window.staticImageUrl + this.productData.bottleImage; }
87
+ else { return window.staticImageUrl + this.productData.assortmentObjects.headline.contentPath; }
88
+ },
89
+
90
+ hasActionSlot() {
91
+ return !!this.$slots.action
92
+ }
93
+ },
94
+
95
+ methods: {
96
+ styleCodeClassName(product) {
97
+ if(product && product.style && product.style.id) {
98
+ return convertStyleCodeToClassName(product.style.id)
99
+ } else {
100
+ return null;
101
+ }
102
+ },
103
+
104
+ bottleShot(product) {
105
+ if (product.bottleImage) {
106
+ return window.staticImageUrl + product.bottleImage;
107
+ } else {
108
+ let find = false;
109
+
110
+ if (product.assortmentObjects.objects) {
111
+ find = product.assortmentObjects.objects.findIndex(item => item.name == "mediumCutout");
112
+ }
113
+
114
+ if(find) {
115
+ return window.staticImageUrl + product.assortmentObjects.objects[find].contentPath;
116
+ } else {
117
+ return window.staticImageUrl + bottleShotPlaceHolderPath;
118
+ }
119
+ }
120
+ },
121
+
122
+ parentElement() {
123
+ return this.$el.parentElement;
124
+ },
125
+
126
+ atb: function() {
127
+ if (!this.productData.id) { return false; }
128
+ Products.addToBasket({ productId: this.productData.id, quantity: 1 })
129
+ .then(() => {
130
+ if (window.nkd && window.nkd.headerCart) { window.nkd.headerCart.reload(); }
131
+ window.notificationCentre.notify({
132
+ title: `1x ${this.productData.heading} added to your basket.`,
133
+ text: 'To checkout, please go to the basket page.',
134
+ group: 'header',
135
+ duration: 8000
136
+ });
137
+ });
138
+ },
139
+ goToUrl: function() { window.location = this.productData.url; }
140
+ },
141
+
142
+ filters: {
143
+ nameChopper: function(val) {
144
+ if (!val) { return false; }
145
+ const maxCharactersTitle = 42;
146
+ return val.length >= maxCharactersTitle ? `${val.substring(0, maxCharactersTitle)} ...` : val;
147
+ },
148
+ }
149
+ };
150
+
151
+ export default productCard;
@@ -0,0 +1,2 @@
1
+ // extracted by mini-css-extract-plugin
2
+ module.exports = {"breakpointXs":"320","breakpointSm":"426","breakpointMd":"768","breakpointLg":"993","breakpointXl":"993"};
package/index.js DELETED
File without changes