@ecomplus/storefront-components 1.0.0-beta.19 → 1.0.0-beta.190

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 (124) hide show
  1. package/CHANGELOG.md +1329 -135
  2. package/all.js +3 -1
  3. package/dist/1.storefront-components.min.js +2 -0
  4. package/dist/1.storefront-components.min.js.map +1 -0
  5. package/dist/2.storefront-components.min.js +5 -0
  6. package/dist/2.storefront-components.min.js.map +1 -0
  7. package/dist/3.storefront-components.min.js +5 -0
  8. package/dist/3.storefront-components.min.js.map +1 -0
  9. package/dist/storefront-components.min.js +33 -12
  10. package/dist/storefront-components.min.js.map +1 -1
  11. package/package.json +17 -12
  12. package/src/APagination.vue +2 -0
  13. package/src/AShare.vue +2 -0
  14. package/src/AccountAddresses.vue +3 -0
  15. package/src/AccountForm.vue +3 -0
  16. package/src/AccountPoints.vue +3 -0
  17. package/src/BuyTogether.vue +3 -0
  18. package/src/EarnPointsProgress.vue +3 -0
  19. package/src/ItemCustomizations.vue +2 -0
  20. package/src/KitProductVariations.vue +3 -0
  21. package/src/PointsApplier.vue +2 -0
  22. package/src/ProductQuickview.vue +3 -0
  23. package/src/QuantitySelector.vue +3 -0
  24. package/src/RecommendedItems.vue +3 -0
  25. package/src/ShippingLine.vue +1 -0
  26. package/src/TheCart.vue +3 -0
  27. package/src/html/APagination.html +90 -0
  28. package/src/html/APrices.html +24 -4
  29. package/src/html/AShare.html +31 -0
  30. package/src/html/AccountAddresses.html +90 -0
  31. package/src/html/AccountForm.html +269 -0
  32. package/src/html/AccountPoints.html +39 -0
  33. package/src/html/AddressForm.html +9 -7
  34. package/src/html/BuyTogether.html +60 -0
  35. package/src/html/CartItem.html +86 -38
  36. package/src/html/CartQuickview.html +28 -5
  37. package/src/html/DiscountApplier.html +3 -3
  38. package/src/html/EarnPointsProgress.html +28 -0
  39. package/src/html/InputDate.html +1 -1
  40. package/src/html/InputDocNumber.html +1 -0
  41. package/src/html/InputPhone.html +1 -1
  42. package/src/html/InstantSearch.html +3 -3
  43. package/src/html/ItemCustomizations.html +14 -0
  44. package/src/html/KitProductVariations.html +92 -0
  45. package/src/html/LoginBlock.html +34 -32
  46. package/src/html/LoginModal.html +9 -4
  47. package/src/html/PaymentOption.html +7 -5
  48. package/src/html/PointsApplier.html +26 -0
  49. package/src/html/ProductCard.html +68 -8
  50. package/src/html/ProductGallery.html +21 -3
  51. package/src/html/ProductQuickview.html +64 -0
  52. package/src/html/ProductVariations.html +30 -3
  53. package/src/html/QuantitySelector.html +85 -0
  54. package/src/html/RecommendedItems.html +48 -0
  55. package/src/html/SearchEngine.html +101 -24
  56. package/src/html/ShippingCalculator.html +84 -3
  57. package/src/html/ShippingLine.html +5 -2
  58. package/src/html/TheAccount.html +43 -9
  59. package/src/html/TheCart.html +156 -0
  60. package/src/html/TheProduct.html +416 -138
  61. package/src/js/APagination.js +74 -0
  62. package/src/js/APicture.js +27 -7
  63. package/src/js/APrices.js +80 -41
  64. package/src/js/AShare.js +83 -0
  65. package/src/js/AccountAddresses.js +201 -0
  66. package/src/js/AccountForm.js +312 -0
  67. package/src/js/AccountPoints.js +63 -0
  68. package/src/js/AddressForm.js +80 -35
  69. package/src/js/BuyTogether.js +246 -0
  70. package/src/js/CartItem.js +67 -14
  71. package/src/js/CartQuickview.js +20 -1
  72. package/src/js/DiscountApplier.js +181 -50
  73. package/src/js/EarnPointsProgress.js +77 -0
  74. package/src/js/InputDate.js +8 -8
  75. package/src/js/InputDocNumber.js +20 -0
  76. package/src/js/ItemCustomizations.js +10 -0
  77. package/src/js/KitProductVariations.js +218 -0
  78. package/src/js/LoginBlock.js +47 -6
  79. package/src/js/LoginModal.js +18 -10
  80. package/src/js/PaymentOption.js +28 -1
  81. package/src/js/PointsApplier.js +110 -0
  82. package/src/js/ProductCard.js +115 -11
  83. package/src/js/ProductGallery.js +32 -12
  84. package/src/js/ProductQuickview.js +72 -0
  85. package/src/js/ProductVariations.js +76 -19
  86. package/src/js/QuantitySelector.js +175 -0
  87. package/src/js/RecommendedItems.js +178 -0
  88. package/src/js/SearchEngine.js +185 -55
  89. package/src/js/ShippingCalculator.js +176 -35
  90. package/src/js/ShippingLine.js +44 -5
  91. package/src/js/TheAccount.js +97 -6
  92. package/src/js/TheCart.js +146 -0
  93. package/src/js/TheProduct.js +387 -43
  94. package/src/js/helpers/add-idle-callback.js +7 -0
  95. package/src/js/helpers/check-form-validity.js +3 -0
  96. package/src/js/helpers/favorite-products.js +24 -0
  97. package/src/js/helpers/scroll-to-element.js +10 -0
  98. package/src/js/helpers/sort-apps.js +14 -0
  99. package/src/js/helpers/wait-storefront-info.js +21 -0
  100. package/src/scss/APicture.scss +2 -0
  101. package/src/scss/APrices.scss +13 -1
  102. package/src/scss/AccountAddresses.scss +27 -0
  103. package/src/scss/AccountForm.scss +5 -0
  104. package/src/scss/AccountPoints.scss +17 -0
  105. package/src/scss/BuyTogether.scss +38 -0
  106. package/src/scss/CartItem.scss +17 -1
  107. package/src/scss/EarnPointsProgress.scss +6 -0
  108. package/src/scss/InstantSearch.scss +1 -0
  109. package/src/scss/KitProductVariations.scss +72 -0
  110. package/src/scss/LoginBlock.scss +5 -0
  111. package/src/scss/PaymentOption.scss +10 -1
  112. package/src/scss/ProductCard.scss +63 -25
  113. package/src/scss/ProductGallery.scss +4 -2
  114. package/src/scss/ProductQuickview.scss +36 -0
  115. package/src/scss/ProductVariations.scss +20 -4
  116. package/src/scss/QuantitySelector.scss +39 -0
  117. package/src/scss/RecommendedItems.scss +28 -0
  118. package/src/scss/SearchEngine.scss +9 -5
  119. package/src/scss/ShippingCalculator.scss +42 -1
  120. package/src/scss/ShippingLine.scss +24 -0
  121. package/src/scss/TheAccount.scss +4 -0
  122. package/src/scss/TheCart.scss +54 -0
  123. package/src/scss/TheProduct.scss +146 -1
  124. package/webpack.config.js +20 -6
@@ -0,0 +1,218 @@
1
+ import {
2
+ i19addToCart,
3
+ i19close,
4
+ i19next,
5
+ i19previous,
6
+ i19quantity,
7
+ i19selectVariationMsg,
8
+ i19item,
9
+ i19minQuantity,
10
+ i19maxQuantity
11
+ } from '@ecomplus/i18n'
12
+
13
+ import {
14
+ i18n,
15
+ name as getName,
16
+ img as getImg,
17
+ randomObjectId as genRandomObjectId
18
+ } from '@ecomplus/utils'
19
+
20
+ import ecomCart from '@ecomplus/shopping-cart'
21
+ import Glide from '@glidejs/glide'
22
+ import APicture from '../APicture.vue'
23
+ import ProductVariations from '../ProductVariations.vue'
24
+ import APrices from '../APrices.vue'
25
+ import ALink from '../ALink.vue'
26
+ import AAlert from '../AAlert.vue'
27
+
28
+ export default {
29
+ name: 'KitProductVariations',
30
+
31
+ components: {
32
+ ALink,
33
+ AAlert,
34
+ APicture,
35
+ APrices,
36
+ ProductVariations
37
+ },
38
+
39
+ props: {
40
+ items: {
41
+ type: Array,
42
+ required: true
43
+ },
44
+ min: {
45
+ type: Number,
46
+ default: 1
47
+ },
48
+ max: Number,
49
+ maxOptionsBtns: {
50
+ type: Number,
51
+ default: 10
52
+ },
53
+ slug: String,
54
+ buyText: String,
55
+ kitProductId: String,
56
+ kitName: String,
57
+ kitPrice: Number,
58
+ canAddToCart: {
59
+ type: Boolean,
60
+ default: true
61
+ },
62
+ glideOptions: {
63
+ type: Object,
64
+ default () {
65
+ return {
66
+ type: 'slider',
67
+ autoplay: false,
68
+ rewind: false
69
+ }
70
+ }
71
+ }
72
+ },
73
+
74
+ data () {
75
+ return {
76
+ glide: null,
77
+ activeIndex: 0,
78
+ selectedVariationId: null,
79
+ variationKit: [],
80
+ variationKitReady: [],
81
+ alertVariant: 'warning'
82
+ }
83
+ },
84
+
85
+ computed: {
86
+ i19addToCart: () => i18n(i19addToCart),
87
+ i19close: () => i18n(i19close),
88
+ i19next: () => i18n(i19next),
89
+ i19previous: () => i18n(i19previous),
90
+ i19selectVariationMsg: () => i18n(i19selectVariationMsg),
91
+ i19quantity: () => i18n(i19quantity),
92
+ i19item: () => i18n(i19item),
93
+ i19minQuantity: () => i18n(i19minQuantity),
94
+ i19maxQuantity: () => i18n(i19maxQuantity),
95
+
96
+ localItems () {
97
+ const products = []
98
+ for (let index = 0; index < this.items.length; index++) {
99
+ if (this.items && this.items.length === this.min) {
100
+ const itemObject = Object.assign({}, this.items[index])
101
+ itemObject.key = genRandomObjectId()
102
+ products.push(itemObject)
103
+ } else {
104
+ for (let i = 0; i < this.min; i++) {
105
+ const itemObject = Object.assign({}, this.items[index])
106
+ itemObject.key = genRandomObjectId()
107
+ products.push(itemObject)
108
+ }
109
+ }
110
+ }
111
+ return products
112
+ }
113
+
114
+ },
115
+
116
+ methods: {
117
+ getImg,
118
+ getName,
119
+
120
+ moveSlider (index) {
121
+ this.activeIndex = index
122
+ if (this.glide) {
123
+ this.glide.go('=' + index)
124
+ }
125
+ },
126
+
127
+ removeItemFromKit (index) {
128
+ this.variationKit.splice(index, 1)
129
+ this.localItems[index].key = genRandomObjectId()
130
+ this.selectedVariationId = null
131
+ this.variationKitReady = this.variationKit.filter(n => n)
132
+ },
133
+
134
+ buy () {
135
+ this.alertVariant = 'warning'
136
+ if (this.variationKitReady.length === this.min) {
137
+ if (this.max === undefined || this.variationKitReady.length <= this.max) {
138
+ const items = []
139
+ const composition = []
140
+ this.variationKitReady.forEach(variationId => {
141
+ const product = this.items.find(item => {
142
+ const variation = item.variations.find(variation => variation._id === variationId)
143
+ if (variation) {
144
+ items.push({
145
+ ...item,
146
+ ...variation,
147
+ variation_id: variation._id
148
+ })
149
+ return item
150
+ }
151
+ })
152
+ if (product) {
153
+ composition.push({
154
+ _id: product.product_id,
155
+ variation_id: variationId,
156
+ quantity: 1
157
+ })
158
+ }
159
+ })
160
+
161
+ items.forEach(item => {
162
+ const newItem = { ...item, quantity: 1 }
163
+ delete newItem.customizations
164
+ if (this.kitProductId) {
165
+ newItem.kit_product = {
166
+ _id: this.kitProductId,
167
+ name: this.kitName,
168
+ pack_quantity: this.min,
169
+ price: this.kitPrice,
170
+ composition
171
+ }
172
+ }
173
+ if (this.slug) {
174
+ newItem.slug = this.slug
175
+ }
176
+ if (this.canAddToCart) {
177
+ ecomCart.addItem(newItem)
178
+ }
179
+ })
180
+ this.$emit('buy', { items })
181
+ }
182
+ }
183
+ }
184
+ },
185
+
186
+ watch: {
187
+ activeIndex (index, oldIndex) {
188
+ if (index < this.localItems.length && index > -1) {
189
+ this.moveSlider(index)
190
+ } else {
191
+ this.moveSlider(oldIndex)
192
+ }
193
+ this.selectedVariationId = null
194
+ },
195
+
196
+ selectedVariationId (current) {
197
+ if (current && this.activeIndex >= 0 && (this.variationKitReady.length < this.min || this.variationKit[this.activeIndex])) {
198
+ this.variationKit[this.activeIndex] = current
199
+ this.variationKitReady = this.variationKit.filter(n => n)
200
+ }
201
+ }
202
+ },
203
+
204
+ mounted () {
205
+ const glide = new Glide(this.$refs.glide, this.glideOptions)
206
+ glide.on('run', () => {
207
+ this.moveSlider(glide.index)
208
+ })
209
+ glide.mount()
210
+ this.glide = glide
211
+ },
212
+
213
+ beforeDestroy () {
214
+ if (this.glide) {
215
+ this.glide.destroy()
216
+ }
217
+ }
218
+ }
@@ -33,6 +33,10 @@ export default {
33
33
  type: Boolean,
34
34
  default: true
35
35
  },
36
+ canFetchOauth: {
37
+ type: Boolean,
38
+ default: true
39
+ },
36
40
  ecomPassport: {
37
41
  type: Object,
38
42
  default () {
@@ -74,7 +78,9 @@ export default {
74
78
  getCustomer().main_email === this.email
75
79
  if (isIdentified) {
76
80
  this.$nextTick(() => {
77
- this.$refs.InputDoc.$el.focus()
81
+ if (this.$refs.InputDoc) {
82
+ this.$refs.InputDoc.$el.focus()
83
+ }
78
84
  })
79
85
  }
80
86
  return isIdentified
@@ -84,7 +90,8 @@ export default {
84
90
  if (!this.isWaitingLogin) {
85
91
  this.isWaitingLogin = true
86
92
  this.failAlertText = null
87
- const { email, docNumber } = this
93
+ const { docNumber } = this
94
+ const email = this.email && this.email.toLowerCase()
88
95
  const isAccountConfirm = this.confirmAccount()
89
96
  const emitUpdate = () => this.$emit('update', { email, docNumber })
90
97
  this.ecomPassport.fetchLogin(email, isAccountConfirm ? docNumber : null)
@@ -111,8 +118,12 @@ export default {
111
118
  }
112
119
  },
113
120
 
114
- oauthPopup (link) {
115
- this.ecomPassport.popupOauthLink(link)
121
+ oauthPopup (fnOrLink) {
122
+ if (typeof fnOrLink === 'function') {
123
+ fnOrLink()
124
+ } else {
125
+ this.ecomPassport.popupOauthLink(fnOrLink)
126
+ }
116
127
  this.isWaitingPopup = true
117
128
  setTimeout(() => {
118
129
  this.isWaitingPopup = false
@@ -131,14 +142,41 @@ export default {
131
142
  },
132
143
 
133
144
  created () {
145
+ if (Array.isArray(window.OAUTH_PROVIDERS)) {
146
+ this.oauthProviders = []
147
+ if (window.OAUTH_PROVIDERS.includes('google') && window.signInWithGoogle) {
148
+ this.oauthProviders.push({
149
+ link: window.signInWithGoogle,
150
+ faIcon: 'fa-google',
151
+ provider: 'google',
152
+ providerName: 'Google'
153
+ })
154
+ }
155
+ if (window.OAUTH_PROVIDERS.includes('facebook') && window.signInWithFacebook) {
156
+ this.oauthProviders.push({
157
+ link: window.signInWithFacebook,
158
+ faIcon: 'fa-facebook-f',
159
+ provider: 'facebook',
160
+ providerName: 'Facebook'
161
+ })
162
+ }
163
+ if (this.oauthProviders.length) return
164
+ }
165
+ if (!this.canFetchOauth) return
134
166
  this.ecomPassport.fetchOauthProviders()
135
167
  .then(({ host, baseUri, oauthPath, providers }) => {
136
168
  const oauthProviders = []
137
169
  for (const provider in providers) {
138
- if (providers[provider]) {
170
+ if (providers[provider] && provider !== 'facebook') {
139
171
  const { faIcon, providerName } = providers[provider]
172
+ let link = host + baseUri + provider + oauthPath
173
+ const referral = typeof window === 'object' &&
174
+ window.sessionStorage.getItem('ecomReferral')
175
+ if (referral) {
176
+ link += `?referral=${referral}`
177
+ }
140
178
  oauthProviders.push({
141
- link: host + baseUri + provider + oauthPath,
179
+ link,
142
180
  faIcon,
143
181
  provider,
144
182
  providerName
@@ -162,6 +200,9 @@ export default {
162
200
  const customer = getCustomer()
163
201
  this.email = customer.main_email
164
202
  this.isCompany = customer.registry_type === 'j'
203
+ if (customer._id && customer.doc_number) {
204
+ this.$emit('login', this.ecomPassport)
205
+ }
165
206
  }
166
207
  }
167
208
  ecomPassport.on('login', () => {
@@ -8,6 +8,7 @@ import {
8
8
  i19login,
9
9
  i19logout,
10
10
  i19myAccount,
11
+ i19myFavorites,
11
12
  i19myOrders,
12
13
  i19noProfileFoundWithEmail,
13
14
  i19signInWith,
@@ -45,6 +46,10 @@ export default {
45
46
  type: String,
46
47
  default: '/app/#/account/orders'
47
48
  },
49
+ favoritesUrl: {
50
+ type: String,
51
+ default: '/app/#/account/favorites'
52
+ },
48
53
  ecomPassport: {
49
54
  type: Object,
50
55
  default () {
@@ -63,19 +68,21 @@ export default {
63
68
  oauthProviders: [],
64
69
  isLoginForm: false,
65
70
  hasLoginError: false,
66
- hasNoProfileFound: false
71
+ hasNoProfileFound: false,
72
+ isWrongCode: false
67
73
  }
68
74
  },
69
75
 
70
76
  computed: {
71
77
  i19close: () => i18n(i19close),
72
78
  i19continueLoginOnPopup: () => i18n(i19continueLoginOnPopup),
73
- i19email: () => i18n(i19email),
79
+ i19email: () => i18n(i19email).toLowerCase(),
74
80
  i19guestCheckoutMsg: () => i18n(i19guestCheckoutMsg),
75
81
  i19loginErrorMsg: () => i18n(i19loginErrorMsg),
76
82
  i19login: () => i18n(i19login),
77
83
  i19logout: () => i18n(i19logout),
78
84
  i19myAccount: () => i18n(i19myAccount),
85
+ i19myFavorites: () => i18n(i19myFavorites),
79
86
  i19myOrders: () => i18n(i19myOrders),
80
87
  i19noProfileFoundWithEmail: () => i18n(i19noProfileFoundWithEmail),
81
88
  i19signInWith: () => i18n(i19signInWith),
@@ -118,10 +125,16 @@ export default {
118
125
  .then(({ host, baseUri, oauthPath, providers }) => {
119
126
  const oauthProviders = []
120
127
  for (const provider in providers) {
121
- if (providers[provider]) {
128
+ if (providers[provider] && provider !== 'facebook') {
122
129
  const { faIcon, providerName } = providers[provider]
130
+ let link = host + baseUri + provider + oauthPath
131
+ const referral = typeof window === 'object' &&
132
+ window.sessionStorage.getItem('ecomReferral')
133
+ if (referral) {
134
+ link += `?referral=${referral}`
135
+ }
123
136
  oauthProviders.push({
124
- link: host + baseUri + provider + oauthPath,
137
+ link,
125
138
  faIcon,
126
139
  provider,
127
140
  providerName
@@ -140,11 +153,6 @@ export default {
140
153
 
141
154
  presetOauthProviders () {
142
155
  this.oauthProviders = [
143
- {
144
- faIcon: 'fa-facebook-f',
145
- providerName: 'Facebook',
146
- provider: 'facebook'
147
- },
148
156
  {
149
157
  faIcon: 'fa-google',
150
158
  providerName: 'Google',
@@ -180,7 +188,7 @@ export default {
180
188
 
181
189
  submitEmail () {
182
190
  this.isLoginForm = false
183
- const promise = this.ecomPassport.fetchLogin(this.email)
191
+ const promise = this.ecomPassport.fetchLogin(this.email.toLowerCase())
184
192
  .catch(err => {
185
193
  const { response } = err
186
194
  if (response && response.status === 403) {
@@ -19,6 +19,7 @@ export default {
19
19
  type: Object,
20
20
  required: true
21
21
  },
22
+ installmentsOption: Object,
22
23
  price: Number
23
24
  },
24
25
 
@@ -43,6 +44,31 @@ export default {
43
44
  return this.paymentGateway.installment_options.concat().sort((a, b) => {
44
45
  return a.number - b.number
45
46
  })
47
+ } else if (
48
+ this.price &&
49
+ this.installmentsOption &&
50
+ this.paymentGateway.payment_method.code === 'credit_card'
51
+ ) {
52
+ const installmentOptions = []
53
+ for (let number = 2; number <= this.installmentsOption.max_number; number++) {
54
+ const tax = this.installmentsOption.monthly_interest > 0
55
+ const minInstallment = this.installmentsOption.min_installment || 5
56
+ let value
57
+ if (!tax) {
58
+ value = this.price / number
59
+ } else {
60
+ const interest = this.installmentsOption.monthly_interest / 100
61
+ value = this.price * interest / (1 - Math.pow(1 + interest, -number))
62
+ }
63
+ if (value >= minInstallment) {
64
+ installmentOptions.push({
65
+ number,
66
+ value,
67
+ tax
68
+ })
69
+ }
70
+ }
71
+ return installmentOptions
46
72
  }
47
73
  },
48
74
 
@@ -51,7 +77,8 @@ export default {
51
77
  if (this.discount.type === 'percentage') {
52
78
  return this.price * (100 - this.discount.value) / 100
53
79
  } else {
54
- return Math.min(this.price - this.discount.value, 0)
80
+ const finalPrice = this.price - this.discount.value
81
+ return (finalPrice > 0 ? finalPrice : 0)
55
82
  }
56
83
  }
57
84
  return this.price
@@ -0,0 +1,110 @@
1
+ import { i19use$1LoyaltyPoints } from '@ecomplus/i18n'
2
+
3
+ import {
4
+ i18n,
5
+ formatMoney
6
+ } from '@ecomplus/utils'
7
+
8
+ import ecomPassport from '@ecomplus/passport-client'
9
+ import waitStorefrontInfo from './helpers/wait-storefront-info'
10
+
11
+ export default {
12
+ name: 'PointsApplier',
13
+
14
+ props: {
15
+ pointsPrograms: Object,
16
+ pointsApplied: {
17
+ type: Object,
18
+ required: true
19
+ },
20
+ pointsAmount: Number,
21
+ maxPointsAmount: Number,
22
+ ecomPassport: {
23
+ type: Object,
24
+ default () {
25
+ return ecomPassport
26
+ }
27
+ }
28
+ },
29
+
30
+ data () {
31
+ return {
32
+ localPointsPrograms: this.pointsPrograms || {},
33
+ availablePoints: {}
34
+ }
35
+ },
36
+
37
+ computed: {
38
+ i19use$1LoyaltyPoints: () => i18n(i19use$1LoyaltyPoints)
39
+ },
40
+
41
+ methods: {
42
+ formatMoney,
43
+
44
+ updatePrograms (pointsPrograms) {
45
+ if (pointsPrograms && Object.keys(pointsPrograms).length) {
46
+ this.localPointsPrograms = pointsPrograms
47
+ this.$emit('update:points-programs', pointsPrograms)
48
+ this.$nextTick(this.fixAvailablePoints)
49
+ }
50
+ },
51
+
52
+ fixAvailablePoints () {
53
+ const pointsEntries = this.ecomPassport.getCustomer().loyalty_points_entries
54
+ this.availablePoints = pointsEntries
55
+ ? pointsEntries.reduce((availablePoints, pointsEntry) => {
56
+ const validThru = pointsEntry.valid_thru
57
+ if (!validThru || new Date(validThru).getTime() >= Date.now()) {
58
+ const programId = pointsEntry.program_id
59
+ const points = pointsEntry.active_points
60
+ if (this.localPointsPrograms[programId]) {
61
+ if (availablePoints[programId]) {
62
+ availablePoints[programId] += points
63
+ } else {
64
+ availablePoints[programId] = points
65
+ }
66
+ if (availablePoints[programId] > pointsEntry.max_points) {
67
+ availablePoints[programId] = pointsEntry.max_points
68
+ }
69
+ const { ratio } = this.localPointsPrograms[programId]
70
+ if (availablePoints[programId] * ratio > this.maxPointsAmount) {
71
+ availablePoints[programId] = this.maxPointsAmount / ratio
72
+ }
73
+ }
74
+ }
75
+ return availablePoints
76
+ }, {})
77
+ : {}
78
+ },
79
+
80
+ getPointsAmount (programId) {
81
+ return this.availablePoints[programId] * this.localPointsPrograms[programId].ratio
82
+ },
83
+
84
+ togglePoints (programId, isChecked) {
85
+ const pointsApplied = {}
86
+ if (isChecked) {
87
+ pointsApplied[programId] = this.availablePoints[programId]
88
+ }
89
+ this.$emit('update:points-applied', pointsApplied)
90
+ let pointsAmount = 0
91
+ for (programId in pointsApplied) {
92
+ pointsAmount += this.getPointsAmount(programId)
93
+ }
94
+ this.$emit('update:points-amount', pointsAmount)
95
+ }
96
+ },
97
+
98
+ created () {
99
+ if (!this.pointsPrograms || !Object.keys(this.pointsPrograms).length) {
100
+ waitStorefrontInfo('list_payments', 'loyalty_points_programs')
101
+ .then(this.updatePrograms)
102
+ } else {
103
+ this.fixAvailablePoints()
104
+ }
105
+ this.ecomPassport.on('login', this.fixAvailablePoints)
106
+ this.$once('hook:beforeDestroy', () => {
107
+ this.ecomPassport.off('login', this.fixAvailablePoints)
108
+ })
109
+ }
110
+ }