@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
@@ -26,6 +26,75 @@
26
26
  class="card-body"
27
27
  :key="searchFilterId"
28
28
  >
29
+ <div
30
+ v-if="hasSetPriceRange || priceOptions.length"
31
+ class="search-engine__filter search-engine__filter--price"
32
+ >
33
+ <h5>{{ i19price }}</h5>
34
+ <a
35
+ v-if="hasSetPriceRange"
36
+ href="#"
37
+ class="btn btn-link btn-sm mb-2"
38
+ @click.prevent="setPriceRange()"
39
+ >
40
+ <i class="i-arrow-left mr-1"></i>
41
+ {{ i19all }}
42
+ </a>
43
+
44
+ <div
45
+ class="search-engine__option custom-control custom-radio"
46
+ v-for="({ label, min, max }, index) in priceOptions"
47
+ :key="`Price-${index}`"
48
+ >
49
+ <input
50
+ type="radio"
51
+ class="custom-control-input"
52
+ name="price-option"
53
+ :id="`Price-${index}`"
54
+ @click="setPriceRange(min, max)"
55
+ >
56
+ <label
57
+ class="custom-control-label"
58
+ :for="`Price-${index}`"
59
+ >
60
+ {{ label }}
61
+ </label>
62
+ </div>
63
+
64
+ <div
65
+ v-if="priceRange.max - priceRange.min > 2"
66
+ class="search-engine__option-range input-group input-group-sm mt-2"
67
+ >
68
+ <input
69
+ ref="inputMinPrice"
70
+ type="text"
71
+ class="form-control"
72
+ aria-describedby="search-engine-price-range"
73
+ :aria-label="`Min ${i19price}`"
74
+ :placeholder="`Min: ${Math.floor(priceRange.min)}`"
75
+ >
76
+ <input
77
+ ref="inputMaxPrice"
78
+ type="text"
79
+ class="form-control"
80
+ aria-label="Max"
81
+ aria-describedby="search-engine-price-range"
82
+ :aria-label="`Max ${i19price}`"
83
+ :placeholder="`Max: ${Math.ceil(priceRange.max)}`"
84
+ >
85
+ <div class="input-group-append">
86
+ <button
87
+ class="btn btn-outline-secondary"
88
+ type="button"
89
+ id="search-engine-price-range"
90
+ @click="handlePriceInputs()"
91
+ >
92
+ <i class="i-chevron-right"></i>
93
+ </button>
94
+ </div>
95
+ </div>
96
+ </div>
97
+
29
98
  <div
30
99
  v-for="({ filter, options, isSpec }, i) in filters"
31
100
  v-if="options.length"
@@ -35,15 +104,14 @@
35
104
  >
36
105
  <template v-once>
37
106
  <button
38
- class="btn"
107
+ class="btn text-truncate"
39
108
  type="button"
40
109
  data-toggle="collapse"
41
110
  :data-target="`#collapse-${filter}`"
42
111
  :aria-expanded="i < 5 ? 'true' : 'false'"
43
112
  :aria-controls="`collapse-${filter}`"
44
113
  >
45
- <i class="fas fa-chevron-down"></i>
46
- <i class="fas fa-chevron-up"></i>
114
+ <i class="i-chevron-down"></i><i class="i-chevron-up"></i>
47
115
  {{ getFilterLabel(filter) }}
48
116
  </button>
49
117
 
@@ -56,6 +124,7 @@
56
124
  class="search-engine__option custom-control custom-checkbox"
57
125
  v-for="(opt, index) in options"
58
126
  :key="`${filter}-${index}`"
127
+ :data-opt="opt.key"
59
128
  >
60
129
  <input
61
130
  type="checkbox"
@@ -69,9 +138,7 @@
69
138
  :for="`${filter}-${index}`"
70
139
  >
71
140
  {{ opt.key }}
72
- <small v-if="!isSpec">
73
- ({{ opt.doc_count }})
74
- </small>
141
+ <small v-if="!isSpec">({{ opt.doc_count }})</small>
75
142
  </label>
76
143
  </div>
77
144
  </div>
@@ -86,7 +153,7 @@
86
153
  @click="clearFilters"
87
154
  >
88
155
  <span class="mr-1">
89
- <i class="fas fa-trash-alt"></i>
156
+ <i class="i-trash"></i>
90
157
  </span>
91
158
  {{ i19clearFilters }}
92
159
  </button>
@@ -116,9 +183,9 @@
116
183
  </span>
117
184
  <span v-else>
118
185
  <span class="d-none d-md-inline">
119
- <i class="fas fa-search"></i>
186
+ <i class="i-search"></i>
120
187
  </span>
121
- <i class="fas fa-filter"></i>
188
+ <i class="i-filter"></i>
122
189
  </span>
123
190
  </button>
124
191
  </transition>
@@ -158,8 +225,8 @@
158
225
  @click="toggleFilters(true)"
159
226
  type="button"
160
227
  >
161
- <i class="fas fa-filter mr-1"></i>
162
- <span class="d-none d-md-inline">
228
+ <i class="i-filter mr-1"></i>
229
+ <span class="d-none d-md-inline-block">
163
230
  {{ i19filterResults }}
164
231
  </span>
165
232
  <span class="d-md-none">
@@ -176,7 +243,7 @@
176
243
  aria-haspopup="true"
177
244
  aria-expanded="false"
178
245
  >
179
- <i class="fas fa-sort mr-1"></i>
246
+ <i class="i-sort mr-1"></i>
180
247
  {{ i19sort }}
181
248
  </button>
182
249
 
@@ -188,6 +255,7 @@
188
255
  v-for="({ value, label }, index) in sortOptions"
189
256
  :key="`sort-${index}`"
190
257
  class="dropdown-item"
258
+ :class="`search-engine__sort--${value}`"
191
259
  href="#"
192
260
  @click.prevent="setSortOrder(value)"
193
261
  :active="selectedSortOption === value"
@@ -251,7 +319,7 @@
251
319
  </div>
252
320
  </template>
253
321
 
254
- <h3 v-else-if="popularItems.length">
322
+ <h3 v-else-if="hasEmptyResult && popularItems.length">
255
323
  {{ i19popularProducts }}
256
324
  </h3>
257
325
 
@@ -265,7 +333,7 @@
265
333
  type="button"
266
334
  @click="clearFilters"
267
335
  >
268
- <i class="fas fa-trash-alt mr-1"></i>
336
+ <i class="i-trash mr-1"></i>
269
337
  {{ i19clearFilters }}
270
338
  </button>
271
339
 
@@ -276,7 +344,7 @@
276
344
  v-for="option in options"
277
345
  @click="setFilterOption(filter, option, false)"
278
346
  >
279
- <i class="fas fa-times mr-1"></i>
347
+ <i class="i-times mr-1"></i>
280
348
  {{ option }}
281
349
  <small>{{ getFilterLabel(filter) }}</small>
282
350
  </button>
@@ -285,12 +353,16 @@
285
353
  </transition>
286
354
  </div>
287
355
 
288
- <article class="search-engine__retail">
356
+ <article
357
+ v-if="canShowItems"
358
+ class="search-engine__retail"
359
+ >
289
360
  <div class="row">
290
361
  <div
291
362
  class="col-6 col-md-4 col-lg-3"
292
- v-for="product in suggestedItems"
363
+ v-for="(product, i) in suggestedItems"
293
364
  :key="product._id"
365
+ :ref="i === pageAnchorIndex ? 'pageAnchor' : null"
294
366
  >
295
367
  <slot
296
368
  name="product-card"
@@ -312,7 +384,7 @@
312
384
  role="alert"
313
385
  v-if="hasNetworkError"
314
386
  >
315
- <i class="fas fa-wifi mr-2"></i>
387
+ <i class="i-wifi mr-2"></i>
316
388
  {{ i19searchOfflineErrorMsg }}
317
389
  <a
318
390
  href="#"
@@ -331,10 +403,15 @@
331
403
  <slot v-if="!hasSearched || isLoadingMore"/>
332
404
  </transition>
333
405
 
334
- <div
335
- v-if="resultItems.length < totalSearchResults"
336
- :key="lastRequestId"
337
- id="search-engine-load-more"
338
- style="width: 100%; margin-top: 20px; height: 5px"
339
- ></div>
406
+ <component
407
+ :is="loadMoreSelector ? 'portal' : 'div'"
408
+ :selector="loadMoreSelector"
409
+ >
410
+ <div
411
+ v-if="resultItems.length < totalSearchResults"
412
+ :key="lastRequestId"
413
+ id="search-engine-load-more"
414
+ style="width: 100%; margin-top: 20px; height: 5px"
415
+ ></div>
416
+ </component>
340
417
  </section>
@@ -22,8 +22,9 @@
22
22
  <button
23
23
  class="btn btn-outline-secondary"
24
24
  type="submit"
25
+ :aria-label="i19calculateShipping"
25
26
  >
26
- <i class="fas fa-shipping-fast"></i>
27
+ <i class="i-shipping-fast"></i>
27
28
  </button>
28
29
  </div>
29
30
  </div>
@@ -49,6 +50,19 @@
49
50
  key="services"
50
51
  class="list-group"
51
52
  >
53
+ <transition
54
+ enter-active-class="animated fadeInUp"
55
+ leave-active-class="animated fadeOutDown"
56
+ >
57
+ <div
58
+ v-if="canSelectServices && !canAutoSelectService &&
59
+ selectedService === null && shippingServices.length"
60
+ class="shipping-calculator__label"
61
+ >
62
+ <i class="i-arrow-down animated wobble"></i>
63
+ {{ i19selectShippingMsg }}
64
+ </div>
65
+ </transition>
52
66
  <component
53
67
  :is="canSelectServices ? 'a' : 'div'"
54
68
  :href="canSelectServices && '#'"
@@ -62,11 +76,78 @@
62
76
  @click.prevent="setSelectedService(i)"
63
77
  >
64
78
  <span class="shipping-calculator__option">
65
- <shipping-line :shipping-line="service.shipping_line"/>
66
- <small>{{ service.label }}</small>
79
+ <slot
80
+ name="option"
81
+ v-bind="{ service }"
82
+ >
83
+ <shipping-line
84
+ :shipping-line="service.shipping_line"
85
+ :production-deadline="productionDeadline"
86
+ :data-service-code="service.service_code"
87
+ />
88
+ <div
89
+ v-if="canSelectServices && !canAutoSelectService"
90
+ class="custom-control custom-radio"
91
+ >
92
+ <input
93
+ type="radio"
94
+ :id="`shipping-method-${service.service_code}`"
95
+ name="shipping-method-select"
96
+ class="custom-control-input"
97
+ :checked="selectedService === i"
98
+ />
99
+ <label
100
+ class="custom-control-label"
101
+ :for="`shipping-method-${service.service_code}`"
102
+ >
103
+ <small>{{ service.label }}</small>
104
+ </label>
105
+ </div>
106
+ <small v-else>{{ service.label }}</small>
107
+ </slot>
67
108
  </span>
68
109
  </component>
69
110
  </div>
70
111
  </transition-group>
112
+
113
+ <transition
114
+ enter-active-class="animated fadeInUp"
115
+ leave-active-class="animated fadeOutDown"
116
+ >
117
+ <div
118
+ v-if="freeFromPercentage"
119
+ class="shipping-calculator__free-from-value"
120
+ >
121
+ <slot
122
+ name="free-from-value"
123
+ v-bind="{ amountSubtotal, freeFromValue, freeFromPercentage }"
124
+ >
125
+ <span>
126
+ {{ i19add$1ToEarn.replace('$1', formatMoney(freeFromValue - amountSubtotal)) }}
127
+ <strong>{{ i19freeShipping }}</strong>
128
+ </span>
129
+
130
+ <div
131
+ v-if="freeFromPercentage >= 33"
132
+ class="progress"
133
+ >
134
+ <div
135
+ class="progress-bar progress-bar-striped"
136
+ role="progressbar"
137
+ :style="`width: ${freeFromPercentage}%`"
138
+ :aria-valuenow="freeFromPercentage"
139
+ aria-valuemin="0"
140
+ aria-valuemax="100"
141
+ >
142
+ <span>
143
+ {{ i19freeShipping }}
144
+ <i class="i-truck mx-1"></i>
145
+ <strong>{{ freeFromPercentage }}%</strong>
146
+ </span>
147
+ </div>
148
+ </div>
149
+ </slot>
150
+ </div>
151
+ </transition>
71
152
  </div>
72
153
  </div>
@@ -1,8 +1,11 @@
1
1
  <div class="shipping-line">
2
- <strong>
2
+ <strong class="mr-2">
3
3
  {{ deadlineStr }}
4
4
  </strong>
5
- <span class="mx-2">
5
+ <span class="mr-2">
6
6
  {{ freightValueStr }}
7
7
  </span>
8
+ <small v-if="shippingLine.delivery_instructions">
9
+ {{ shippingLine.delivery_instructions }}
10
+ </small>
8
11
  </div>
@@ -4,7 +4,7 @@
4
4
  class="account__logged"
5
5
  >
6
6
  <h2 class="account__greetings">
7
- <i class="fas fa-user-circle"></i>
7
+ <i class="i-user-circle"></i>
8
8
  {{ `${i19hello} ${nickname}` }}
9
9
  </h2>
10
10
 
@@ -14,21 +14,21 @@
14
14
  href="#"
15
15
  @click.prevent="logout"
16
16
  >
17
- <i class="fas fa-sign-out-alt"></i>
17
+ <i class="i-sign-out"></i>
18
18
  {{ i19logout }}
19
19
  </a>
20
20
  </div>
21
21
 
22
22
  <ul class="account__nav nav nav-tabs">
23
23
  <li
24
- v-for="(label, i) in [i19registration, i19orders]"
24
+ v-for="({ label, value }) in navTabs"
25
25
  class="nav-item"
26
26
  >
27
27
  <a
28
28
  class="nav-link"
29
- :class="activeTab === i ? 'active' : null"
29
+ :class="activeTab === value ? 'active' : null"
30
30
  href="#"
31
- @click.prevent="activeTab = i"
31
+ @click.prevent="activeTab = value"
32
32
  >
33
33
  {{ label }}
34
34
  </a>
@@ -40,13 +40,13 @@
40
40
  enter-active-class="animated fadeInLeft slow"
41
41
  leave-active-class="animated fadeOutLeft"
42
42
  >
43
- <div v-if="!isOrdersList">
43
+ <div v-if="currentTab === 'account' || !currentTab">
44
44
  <slot name="registration">
45
45
  <div class="row">
46
- <div class="col-lg-8 col-md-7">
46
+ <div class="col-md-7">
47
47
  <slot name="account-form"/>
48
48
  </div>
49
- <div class="col-lg-4 col-md-5 mt-3 mt-md-0">
49
+ <div class="col-md-5 mt-3 mt-md-0">
50
50
  <h4>{{ i19addresses }}</h4>
51
51
  <slot name="account-addresses"/>
52
52
  </div>
@@ -59,10 +59,44 @@
59
59
  enter-active-class="animated fadeInRight slow"
60
60
  leave-active-class="animated fadeOutRight position-absolute"
61
61
  >
62
- <div v-if="isOrdersList">
62
+ <div v-if="currentTab === 'orders'">
63
63
  <slot name="orders-list"/>
64
64
  </div>
65
65
  </transition>
66
+
67
+ <transition
68
+ enter-active-class="animated fadeInRight slow"
69
+ leave-active-class="animated fadeOutRight position-absolute"
70
+ >
71
+ <div v-if="currentTab === 'favorites'">
72
+ <slot name="favorites">
73
+ <recommended-items
74
+ v-if="favoriteIds.length"
75
+ :product-ids="favoriteIds"
76
+ >
77
+ </recommended-items>
78
+ <div v-else>
79
+ {{ i19noSavedFavoritesMsg }}
80
+ </div>
81
+ </slot>
82
+ </div>
83
+ </transition>
84
+ <transition
85
+ enter-active-class="animated fadeInRight slow"
86
+ leave-active-class="animated fadeOutRight position-absolute"
87
+ >
88
+ <div v-if="currentTab === 'points'">
89
+ <slot name="account-points"/>
90
+ </div>
91
+ </transition>
92
+ <transition
93
+ enter-active-class="animated fadeInRight slow"
94
+ leave-active-class="animated fadeOutRight position-absolute"
95
+ >
96
+ <div v-if="currentTab === 'subscriptions'">
97
+ <slot name="subscriptions" />
98
+ </div>
99
+ </transition>
66
100
  </div>
67
101
  </div>
68
102
 
@@ -0,0 +1,156 @@
1
+ <div class="cart">
2
+ <transition-group enter-active-class="animated fadeInDown">
3
+ <div
4
+ class="row"
5
+ v-if="cart.items.length"
6
+ key="list"
7
+ >
8
+ <div class="col-md-7 col-lg-8">
9
+ <div class="cart__list">
10
+ <slot
11
+ name="list"
12
+ v-bind="{ items: cart.items }"
13
+ >
14
+ <transition-group
15
+ enter-active-class="animated fadeInDown"
16
+ leave-active-class="animated fadeOutUp faster position-absolute"
17
+ >
18
+ <cart-item
19
+ v-for="item in cart.items"
20
+ :key="item._id"
21
+ :item="item"
22
+ :name-max-length="80"
23
+ />
24
+ </transition-group>
25
+ </slot>
26
+ </div>
27
+
28
+ <earn-points-progress
29
+ class="my-3"
30
+ :cart-subtotal="cart.subtotal"
31
+ />
32
+
33
+ <recommended-items col-class-name="col-6 col-lg-3"/>
34
+
35
+ <slot name="back-shopping">
36
+ <div class="cart__back d-none d-md-block my-4">
37
+ <a
38
+ class="cart__btn-back btn btn-link"
39
+ role="button"
40
+ href="/"
41
+ >
42
+ <i class="i-arrow-left mr-1"></i>
43
+ {{ i19continueShopping }}
44
+ </a>
45
+ </div>
46
+ </slot>
47
+ </div>
48
+
49
+ <div class="col-md-5 col-lg-4 mt-3 mt-md-0">
50
+ <div class="cart__info">
51
+ <slot name="info">
52
+ <div
53
+ class="cart__summary-row"
54
+ :data-subtotal="cart.subtotal.toFixed(2)"
55
+ >
56
+ <span>Subtotal</span>
57
+ <div>{{ formatMoney(cart.subtotal) }}</div>
58
+ </div>
59
+
60
+ <template v-if="isValidCart">
61
+ <transition enter-active-class="animated fadeInDown">
62
+ <div
63
+ class="cart__summary-row mt-1"
64
+ v-if="amount.discount"
65
+ :data-discount="amount.discount.toFixed(2)"
66
+ >
67
+ <span>
68
+ <i class="i-tag mr-1"></i>
69
+ {{ i19discount }}
70
+ </span>
71
+ <div>{{ formatMoney(amount.discount) }}</div>
72
+ </div>
73
+ </transition>
74
+
75
+ <shipping-calculator
76
+ class="cart__shipping"
77
+ :can-select-services="true"
78
+ :shipped-items="cart.items"
79
+ :zip-code.sync="localZipCode"
80
+ @select-service="selectShippingService"
81
+ />
82
+
83
+ <div
84
+ class="cart__summary-row cart__total"
85
+ :data-total="(amount.total || cart.subtotal).toFixed(2)"
86
+ >
87
+ <span>Total</span>
88
+ <a-prices
89
+ :product="{ price: amount.total || cart.subtotal }"
90
+ :discount-option="{ value: amount.discount }"
91
+ :is-literal="true"
92
+ :is-amount-total="true"
93
+ />
94
+ </div>
95
+ </template>
96
+
97
+ <slot name="checkout">
98
+ <a
99
+ v-if="isValidCart"
100
+ class="cart__btn-checkout btn btn-lg btn-block btn-success"
101
+ role="button"
102
+ :href="checkoutUrl"
103
+ >
104
+ <span class="mr-1">
105
+ <i class="i-shopping-bag"></i>
106
+ </span>
107
+ {{ i19checkout }}
108
+ </a>
109
+
110
+ <a
111
+ class="cart__btn-back btn btn-block btn-outline-secondary"
112
+ :class="isValidCart ? 'd-md-none' : 'mt-3'"
113
+ role="button"
114
+ href="/"
115
+ >
116
+ <i class="i-arrow-left mr-1"></i>
117
+ {{ i19continueShopping }}
118
+ </a>
119
+ </slot>
120
+ </slot>
121
+ </div>
122
+
123
+ <discount-applier
124
+ v-if="isValidCart && canApplyDiscount"
125
+ class="cart__discount"
126
+ :amount="amount"
127
+ :is-coupon-applied="isCouponApplied"
128
+ :coupon-code.sync="localDiscountCoupon"
129
+ @set-discount-rule="setDiscountRule"
130
+ :modules-payload="modulesPayload"
131
+ />
132
+ </div>
133
+ </div>
134
+
135
+ <div
136
+ v-else
137
+ class="cart__empty"
138
+ key="empty"
139
+ >
140
+ <slot name="empty">
141
+ <p class="lead text-muted">
142
+ {{ i19emptyCart }} ...
143
+ </p>
144
+ <a
145
+ class="btn btn-primary"
146
+ href="/"
147
+ >
148
+ <span class="mr-1">
149
+ <i class="i-arrow-left"></i>
150
+ </span>
151
+ {{ i19continueShopping }}
152
+ </a>
153
+ </slot>
154
+ </div>
155
+ </transition-group>
156
+ </div>