@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.
- package/CHANGELOG.md +1329 -135
- package/all.js +3 -1
- package/dist/1.storefront-components.min.js +2 -0
- package/dist/1.storefront-components.min.js.map +1 -0
- package/dist/2.storefront-components.min.js +5 -0
- package/dist/2.storefront-components.min.js.map +1 -0
- package/dist/3.storefront-components.min.js +5 -0
- package/dist/3.storefront-components.min.js.map +1 -0
- package/dist/storefront-components.min.js +33 -12
- package/dist/storefront-components.min.js.map +1 -1
- package/package.json +17 -12
- package/src/APagination.vue +2 -0
- package/src/AShare.vue +2 -0
- package/src/AccountAddresses.vue +3 -0
- package/src/AccountForm.vue +3 -0
- package/src/AccountPoints.vue +3 -0
- package/src/BuyTogether.vue +3 -0
- package/src/EarnPointsProgress.vue +3 -0
- package/src/ItemCustomizations.vue +2 -0
- package/src/KitProductVariations.vue +3 -0
- package/src/PointsApplier.vue +2 -0
- package/src/ProductQuickview.vue +3 -0
- package/src/QuantitySelector.vue +3 -0
- package/src/RecommendedItems.vue +3 -0
- package/src/ShippingLine.vue +1 -0
- package/src/TheCart.vue +3 -0
- package/src/html/APagination.html +90 -0
- package/src/html/APrices.html +24 -4
- package/src/html/AShare.html +31 -0
- package/src/html/AccountAddresses.html +90 -0
- package/src/html/AccountForm.html +269 -0
- package/src/html/AccountPoints.html +39 -0
- package/src/html/AddressForm.html +9 -7
- package/src/html/BuyTogether.html +60 -0
- package/src/html/CartItem.html +86 -38
- package/src/html/CartQuickview.html +28 -5
- package/src/html/DiscountApplier.html +3 -3
- package/src/html/EarnPointsProgress.html +28 -0
- package/src/html/InputDate.html +1 -1
- package/src/html/InputDocNumber.html +1 -0
- package/src/html/InputPhone.html +1 -1
- package/src/html/InstantSearch.html +3 -3
- package/src/html/ItemCustomizations.html +14 -0
- package/src/html/KitProductVariations.html +92 -0
- package/src/html/LoginBlock.html +34 -32
- package/src/html/LoginModal.html +9 -4
- package/src/html/PaymentOption.html +7 -5
- package/src/html/PointsApplier.html +26 -0
- package/src/html/ProductCard.html +68 -8
- package/src/html/ProductGallery.html +21 -3
- package/src/html/ProductQuickview.html +64 -0
- package/src/html/ProductVariations.html +30 -3
- package/src/html/QuantitySelector.html +85 -0
- package/src/html/RecommendedItems.html +48 -0
- package/src/html/SearchEngine.html +101 -24
- package/src/html/ShippingCalculator.html +84 -3
- package/src/html/ShippingLine.html +5 -2
- package/src/html/TheAccount.html +43 -9
- package/src/html/TheCart.html +156 -0
- package/src/html/TheProduct.html +416 -138
- package/src/js/APagination.js +74 -0
- package/src/js/APicture.js +27 -7
- package/src/js/APrices.js +80 -41
- package/src/js/AShare.js +83 -0
- package/src/js/AccountAddresses.js +201 -0
- package/src/js/AccountForm.js +312 -0
- package/src/js/AccountPoints.js +63 -0
- package/src/js/AddressForm.js +80 -35
- package/src/js/BuyTogether.js +246 -0
- package/src/js/CartItem.js +67 -14
- package/src/js/CartQuickview.js +20 -1
- package/src/js/DiscountApplier.js +181 -50
- package/src/js/EarnPointsProgress.js +77 -0
- package/src/js/InputDate.js +8 -8
- package/src/js/InputDocNumber.js +20 -0
- package/src/js/ItemCustomizations.js +10 -0
- package/src/js/KitProductVariations.js +218 -0
- package/src/js/LoginBlock.js +47 -6
- package/src/js/LoginModal.js +18 -10
- package/src/js/PaymentOption.js +28 -1
- package/src/js/PointsApplier.js +110 -0
- package/src/js/ProductCard.js +115 -11
- package/src/js/ProductGallery.js +32 -12
- package/src/js/ProductQuickview.js +72 -0
- package/src/js/ProductVariations.js +76 -19
- package/src/js/QuantitySelector.js +175 -0
- package/src/js/RecommendedItems.js +178 -0
- package/src/js/SearchEngine.js +185 -55
- package/src/js/ShippingCalculator.js +176 -35
- package/src/js/ShippingLine.js +44 -5
- package/src/js/TheAccount.js +97 -6
- package/src/js/TheCart.js +146 -0
- package/src/js/TheProduct.js +387 -43
- package/src/js/helpers/add-idle-callback.js +7 -0
- package/src/js/helpers/check-form-validity.js +3 -0
- package/src/js/helpers/favorite-products.js +24 -0
- package/src/js/helpers/scroll-to-element.js +10 -0
- package/src/js/helpers/sort-apps.js +14 -0
- package/src/js/helpers/wait-storefront-info.js +21 -0
- package/src/scss/APicture.scss +2 -0
- package/src/scss/APrices.scss +13 -1
- package/src/scss/AccountAddresses.scss +27 -0
- package/src/scss/AccountForm.scss +5 -0
- package/src/scss/AccountPoints.scss +17 -0
- package/src/scss/BuyTogether.scss +38 -0
- package/src/scss/CartItem.scss +17 -1
- package/src/scss/EarnPointsProgress.scss +6 -0
- package/src/scss/InstantSearch.scss +1 -0
- package/src/scss/KitProductVariations.scss +72 -0
- package/src/scss/LoginBlock.scss +5 -0
- package/src/scss/PaymentOption.scss +10 -1
- package/src/scss/ProductCard.scss +63 -25
- package/src/scss/ProductGallery.scss +4 -2
- package/src/scss/ProductQuickview.scss +36 -0
- package/src/scss/ProductVariations.scss +20 -4
- package/src/scss/QuantitySelector.scss +39 -0
- package/src/scss/RecommendedItems.scss +28 -0
- package/src/scss/SearchEngine.scss +9 -5
- package/src/scss/ShippingCalculator.scss +42 -1
- package/src/scss/ShippingLine.scss +24 -0
- package/src/scss/TheAccount.scss +4 -0
- package/src/scss/TheCart.scss +54 -0
- package/src/scss/TheProduct.scss +146 -1
- package/webpack.config.js +20 -6
package/src/html/LoginBlock.html
CHANGED
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
{{ i19enterYourEmailMsg }}
|
|
8
8
|
</label>
|
|
9
9
|
|
|
10
|
-
<div class="input-group input-group-lg">
|
|
10
|
+
<div class="login__email input-group input-group-lg">
|
|
11
11
|
<input
|
|
12
12
|
ref="inputEmail"
|
|
13
13
|
type="email"
|
|
14
14
|
class="form-control"
|
|
15
15
|
id="login-email"
|
|
16
16
|
placeholder="email@mail.com"
|
|
17
|
-
v-model="email"
|
|
17
|
+
v-model.trim="email"
|
|
18
18
|
:readonly="isWaitingLogin"
|
|
19
19
|
required
|
|
20
20
|
>
|
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
<div class="input-group-append">
|
|
23
23
|
<button
|
|
24
24
|
type="submit"
|
|
25
|
-
class="btn btn-primary"
|
|
25
|
+
class="login__email-btn btn btn-primary"
|
|
26
26
|
:disabled="isWaitingLogin"
|
|
27
27
|
>
|
|
28
28
|
<span
|
|
29
29
|
v-if="!isWaitingLogin"
|
|
30
30
|
key="login"
|
|
31
31
|
>
|
|
32
|
-
<i class="
|
|
32
|
+
<i class="i-arrow-right"></i>
|
|
33
33
|
<span class="d-none d-md-inline ml-1">
|
|
34
34
|
{{ i19continue }}
|
|
35
35
|
</span>
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
:disabled="isWaitingLogin"
|
|
84
84
|
:aria-label="i19continue"
|
|
85
85
|
>
|
|
86
|
-
<i class="
|
|
86
|
+
<i class="i-check"></i>
|
|
87
87
|
</button>
|
|
88
88
|
</div>
|
|
89
89
|
</div>
|
|
@@ -97,37 +97,39 @@
|
|
|
97
97
|
{{ failAlertText }}
|
|
98
98
|
</a-alert>
|
|
99
99
|
|
|
100
|
-
<
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
<p class="lead">
|
|
106
|
-
{{ i19orProceedWith }}:
|
|
107
|
-
</p>
|
|
108
|
-
|
|
109
|
-
<button
|
|
110
|
-
v-for="({ link, faIcon, providerName, provider }) in oauthProviders"
|
|
111
|
-
type="button"
|
|
112
|
-
class="btn login__btn"
|
|
113
|
-
:key="provider"
|
|
114
|
-
:class="`login__btn--${provider}`"
|
|
115
|
-
@click="() => oauthPopup(link)"
|
|
100
|
+
<slot name="login-methods" v-bind="{ isWaitingLogin, email, confirmAccount }">
|
|
101
|
+
<transition enter-active-class="animated fadeInUp">
|
|
102
|
+
<div
|
|
103
|
+
v-if="oauthProviders.length"
|
|
104
|
+
class="login__oauth"
|
|
116
105
|
>
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
106
|
+
<p class="lead">
|
|
107
|
+
{{ i19orProceedWith }}:
|
|
108
|
+
</p>
|
|
109
|
+
|
|
110
|
+
<button
|
|
111
|
+
v-for="({ link, faIcon, providerName, provider }) in oauthProviders"
|
|
112
|
+
type="button"
|
|
113
|
+
class="btn login__btn"
|
|
114
|
+
:key="provider"
|
|
115
|
+
:class="`login__btn--${provider}`"
|
|
116
|
+
@click="() => oauthPopup(link)"
|
|
117
|
+
>
|
|
118
|
+
<small>{{ i19signInWith }}</small>
|
|
119
|
+
<i
|
|
120
|
+
class="fab mr-2"
|
|
121
|
+
:class="faIcon"
|
|
122
|
+
></i>
|
|
123
|
+
{{ providerName }}
|
|
124
|
+
</button>
|
|
125
|
+
</div>
|
|
126
|
+
</transition>
|
|
127
|
+
</slot>
|
|
126
128
|
</form>
|
|
127
129
|
|
|
128
130
|
<div class="login__info">
|
|
129
131
|
<div class="login__info-title">
|
|
130
|
-
<i class="
|
|
132
|
+
<i class="i-lock"></i>
|
|
131
133
|
{{ i19weUseYourDataToMsg }}:
|
|
132
134
|
</div>
|
|
133
135
|
|
|
@@ -135,7 +137,7 @@
|
|
|
135
137
|
class="login__info-row"
|
|
136
138
|
v-for="label in [i19identifyYourAccount, i19notifyAboutOrders, i19manageYourPurchaseHistory]"
|
|
137
139
|
>
|
|
138
|
-
<i class="
|
|
140
|
+
<i class="i-check"></i>
|
|
139
141
|
{{ label }}
|
|
140
142
|
</div>
|
|
141
143
|
</div>
|
package/src/html/LoginModal.html
CHANGED
|
@@ -68,6 +68,12 @@
|
|
|
68
68
|
>
|
|
69
69
|
{{ i19myAccount }}
|
|
70
70
|
</a-link>
|
|
71
|
+
<a-link
|
|
72
|
+
:href="favoritesUrl"
|
|
73
|
+
class="list-group-item list-group-item-action"
|
|
74
|
+
>
|
|
75
|
+
{{ i19myFavorites }}
|
|
76
|
+
</a-link>
|
|
71
77
|
</div>
|
|
72
78
|
|
|
73
79
|
<button
|
|
@@ -75,7 +81,7 @@
|
|
|
75
81
|
type="button"
|
|
76
82
|
@click="logout"
|
|
77
83
|
>
|
|
78
|
-
<i class="
|
|
84
|
+
<i class="i-sign-out"></i>
|
|
79
85
|
{{ i19logout }}
|
|
80
86
|
</button>
|
|
81
87
|
</div>
|
|
@@ -131,7 +137,7 @@
|
|
|
131
137
|
@click="isLoginForm = true"
|
|
132
138
|
>
|
|
133
139
|
<span class="login-modal__btn-icon">
|
|
134
|
-
<i class="
|
|
140
|
+
<i class="i-envelope"></i>
|
|
135
141
|
</span>
|
|
136
142
|
{{ `${i19signInWith} ${i19email}` }}
|
|
137
143
|
</button>
|
|
@@ -154,9 +160,8 @@
|
|
|
154
160
|
type="button"
|
|
155
161
|
@click="isLoginForm = false"
|
|
156
162
|
>
|
|
157
|
-
<i class="
|
|
163
|
+
<i class="i-arrow-left"></i>
|
|
158
164
|
</button>
|
|
159
|
-
|
|
160
165
|
<label for="login-modal-email">
|
|
161
166
|
{{ `${i19signInWith} ${i19email}` }}
|
|
162
167
|
</label>
|
|
@@ -49,17 +49,19 @@
|
|
|
49
49
|
v-if="installmentOptions"
|
|
50
50
|
class="payment-option__installment list-unstyled"
|
|
51
51
|
>
|
|
52
|
-
<
|
|
52
|
+
<li
|
|
53
53
|
v-for="({ number, value, tax }) in installmentOptions"
|
|
54
54
|
v-if="number > 1"
|
|
55
55
|
>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
<span>
|
|
57
|
+
{{ `${number}x` }}
|
|
58
|
+
<small>{{ i19of }}</small>
|
|
59
|
+
{{ formatMoney(value) }}
|
|
60
|
+
</span>
|
|
59
61
|
<small v-if="!tax">
|
|
60
62
|
{{ i19interestFree }}
|
|
61
63
|
</small>
|
|
62
|
-
</
|
|
64
|
+
</li>
|
|
63
65
|
</ul>
|
|
64
66
|
</div>
|
|
65
67
|
</div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<div class="points-applier">
|
|
2
|
+
<div
|
|
3
|
+
v-for="({ name }, programId) in localPointsPrograms"
|
|
4
|
+
v-if="availablePoints[programId] >= 0.1"
|
|
5
|
+
class="custom-control custom-switch"
|
|
6
|
+
>
|
|
7
|
+
<input
|
|
8
|
+
type="checkbox"
|
|
9
|
+
class="custom-control-input"
|
|
10
|
+
:id="`points-applier-${programId}`"
|
|
11
|
+
:checked="pointsApplied[programId]"
|
|
12
|
+
@change="ev => togglePoints(programId, ev.target.checked)"
|
|
13
|
+
>
|
|
14
|
+
|
|
15
|
+
<label
|
|
16
|
+
class="custom-control-label"
|
|
17
|
+
:for="`points-applier-${programId}`"
|
|
18
|
+
>
|
|
19
|
+
<span class="badge badge-info">
|
|
20
|
+
-{{ formatMoney(getPointsAmount(programId)) }}
|
|
21
|
+
</span>
|
|
22
|
+
{{ i19use$1LoyaltyPoints.replace('$1', availablePoints[programId].toFixed(1)) }}
|
|
23
|
+
<em>{{ name }}</em>
|
|
24
|
+
</label>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
'product-card--small': isSmall
|
|
6
6
|
}"
|
|
7
7
|
@mouseover="isHovered = true"
|
|
8
|
+
:data-product-id="body._id"
|
|
9
|
+
:data-sku="body.sku"
|
|
8
10
|
>
|
|
9
|
-
<transition enter-active-class="
|
|
11
|
+
<transition :enter-active-class="transitionClass">
|
|
10
12
|
<section v-if="!isLoading">
|
|
11
13
|
<slot
|
|
12
14
|
name="discount-tag"
|
|
@@ -16,10 +18,23 @@
|
|
|
16
18
|
v-if="isActive && discount > 0"
|
|
17
19
|
class="product-card__offer-stamp"
|
|
18
20
|
>
|
|
19
|
-
<i class="
|
|
21
|
+
<i class="i-arrow-down"></i> <b>{{ discount }}</b>%
|
|
20
22
|
</span>
|
|
21
23
|
</slot>
|
|
22
24
|
|
|
25
|
+
<slot name="stamps">
|
|
26
|
+
<div v-if="validStamps.length" class="product-card__stamps">
|
|
27
|
+
<span
|
|
28
|
+
v-for="(stamp, i) in validStamps"
|
|
29
|
+
:key="`s-${i}`"
|
|
30
|
+
:class="'product-card__stamps-' +
|
|
31
|
+
+ `${(stamp.id || '').toLowerCase().replace(/\s/g, '-')}`"
|
|
32
|
+
>
|
|
33
|
+
<img :src="stamp.img" :alt="stamp.id">
|
|
34
|
+
</span>
|
|
35
|
+
</div>
|
|
36
|
+
</slot>
|
|
37
|
+
|
|
23
38
|
<slot name="body">
|
|
24
39
|
<a-link
|
|
25
40
|
class="product-card__link"
|
|
@@ -61,6 +76,7 @@
|
|
|
61
76
|
v-once
|
|
62
77
|
class="product-card__rating"
|
|
63
78
|
:data-sku="body.sku"
|
|
79
|
+
v-html="ratingHtml"
|
|
64
80
|
></div>
|
|
65
81
|
</slot>
|
|
66
82
|
|
|
@@ -68,7 +84,7 @@
|
|
|
68
84
|
name="unavailable"
|
|
69
85
|
v-if="!body.available || !body.visible"
|
|
70
86
|
>
|
|
71
|
-
<p class="badge badge-warning">
|
|
87
|
+
<p class="badge badge-warning mt-auto">
|
|
72
88
|
{{ i19unavailable }}
|
|
73
89
|
</p>
|
|
74
90
|
</slot>
|
|
@@ -77,16 +93,27 @@
|
|
|
77
93
|
name="out-of-stock"
|
|
78
94
|
v-else-if="!isInStock"
|
|
79
95
|
>
|
|
80
|
-
<p class="badge badge-dark">
|
|
96
|
+
<p class="badge badge-dark mt-auto">
|
|
81
97
|
{{ i19outOfStock }}
|
|
82
98
|
</p>
|
|
83
99
|
</slot>
|
|
84
100
|
|
|
101
|
+
<slot
|
|
102
|
+
name="without-price"
|
|
103
|
+
v-else-if="isWithoutPrice"
|
|
104
|
+
>
|
|
105
|
+
<p class="badge badge-info mt-auto">
|
|
106
|
+
{{ i19uponRequest }}
|
|
107
|
+
</p>
|
|
108
|
+
</slot>
|
|
109
|
+
|
|
85
110
|
<template v-else>
|
|
86
111
|
<slot name="prices">
|
|
87
112
|
<a-prices
|
|
88
113
|
class="product-card__prices"
|
|
89
114
|
:product="body"
|
|
115
|
+
:installments-option="installmentsOption"
|
|
116
|
+
:discount-option="discountOption"
|
|
90
117
|
/>
|
|
91
118
|
</slot>
|
|
92
119
|
|
|
@@ -95,23 +122,54 @@
|
|
|
95
122
|
class="product-card__buy fade"
|
|
96
123
|
>
|
|
97
124
|
<slot name="buy">
|
|
98
|
-
<div
|
|
125
|
+
<div
|
|
126
|
+
v-if="buyHtml"
|
|
127
|
+
v-html="buyHtml"
|
|
128
|
+
></div>
|
|
129
|
+
|
|
99
130
|
<button
|
|
100
131
|
type="button"
|
|
101
132
|
class="btn btn-primary"
|
|
102
133
|
:class="isSmall ? 'btn-sm': 'btn-block'"
|
|
134
|
+
:disabled="isWaitingBuy"
|
|
103
135
|
>
|
|
136
|
+
<span
|
|
137
|
+
v-if="isWaitingBuy"
|
|
138
|
+
class="product-card__buy-loading spinner-grow spinner-grow-sm"
|
|
139
|
+
role="status"
|
|
140
|
+
>
|
|
141
|
+
<span class="sr-only">Loading...</span>
|
|
142
|
+
</span>
|
|
143
|
+
|
|
104
144
|
<slot name="buy-button-content">
|
|
105
|
-
<i class="
|
|
145
|
+
<i class="i-shopping-bag mr-1"></i>
|
|
106
146
|
{{ strBuy }}
|
|
107
147
|
</slot>
|
|
108
148
|
</button>
|
|
109
149
|
</slot>
|
|
110
150
|
</div>
|
|
111
|
-
</template>
|
|
151
|
+
</template>
|
|
152
|
+
|
|
153
|
+
<slot name="favorite">
|
|
154
|
+
<a
|
|
155
|
+
class="btn product-card__favorite fade"
|
|
156
|
+
@click="toggleFavorite"
|
|
157
|
+
:href="isLogged ? null : accountUrl"
|
|
158
|
+
:aria-label="i19addToFavorites"
|
|
159
|
+
>
|
|
160
|
+
<i
|
|
161
|
+
class="i-heart mr-1"
|
|
162
|
+
:class="isFavorite ? 'active' : null"
|
|
163
|
+
>
|
|
164
|
+
</i>
|
|
165
|
+
</a>
|
|
166
|
+
</slot>
|
|
112
167
|
|
|
113
168
|
<slot name="footer">
|
|
114
|
-
<div
|
|
169
|
+
<div
|
|
170
|
+
v-if="footerHtml"
|
|
171
|
+
v-html="footerHtml"
|
|
172
|
+
></div>
|
|
115
173
|
</slot>
|
|
116
174
|
</section>
|
|
117
175
|
</transition>
|
|
@@ -126,4 +184,6 @@
|
|
|
126
184
|
{{ error }}
|
|
127
185
|
</div>
|
|
128
186
|
</template>
|
|
187
|
+
|
|
188
|
+
<div ref="quickview"></div>
|
|
129
189
|
</div>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
:class="{ 'gallery__item--selected': localPictures.length === activeIndex }"
|
|
7
7
|
@click="activeIndex = localPictures.length"
|
|
8
8
|
>
|
|
9
|
-
<i class="
|
|
9
|
+
<i class="i-play"></i>
|
|
10
10
|
<span>{{ i19video }}</span>
|
|
11
11
|
</div>
|
|
12
12
|
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
v-if="localPictures.length > 4"
|
|
29
29
|
type="button"
|
|
30
30
|
class="gallery__open btn btn-dark"
|
|
31
|
+
:style="zoomLinkStyle"
|
|
31
32
|
:title="i19openGallery"
|
|
32
33
|
@click.prevent="openZoom(4)"
|
|
33
34
|
>
|
|
@@ -53,10 +54,19 @@
|
|
|
53
54
|
<div @click="openZoom(i)">
|
|
54
55
|
<slot v-if="i === 0 && !isSliderMoved">
|
|
55
56
|
<a-picture
|
|
57
|
+
v-if="!elFirstPicture"
|
|
56
58
|
class="gallery__big-image"
|
|
59
|
+
:style="zoomLinkStyle"
|
|
57
60
|
:src="getImg(picture, null, 'big')"
|
|
58
61
|
/>
|
|
62
|
+
<div
|
|
63
|
+
v-else
|
|
64
|
+
ref="firstPicture"
|
|
65
|
+
class="gallery__big-image"
|
|
66
|
+
:style="zoomLinkStyle"
|
|
67
|
+
></div>
|
|
59
68
|
</slot>
|
|
69
|
+
|
|
60
70
|
<a-picture
|
|
61
71
|
v-else
|
|
62
72
|
class="gallery__big-image"
|
|
@@ -73,9 +83,17 @@
|
|
|
73
83
|
<div
|
|
74
84
|
class="embed-responsive"
|
|
75
85
|
:class="`embed-responsive-${videoAspectRatio}`"
|
|
76
|
-
>
|
|
86
|
+
>
|
|
87
|
+
<div
|
|
88
|
+
v-if="activeIndex === localPictures.length"
|
|
89
|
+
class="spinner-border text-primary"
|
|
90
|
+
role="status"
|
|
91
|
+
>
|
|
92
|
+
<span class="sr-only">Loading...</span>
|
|
93
|
+
</div>
|
|
77
94
|
<iframe
|
|
78
95
|
class="embed-responsive-item"
|
|
96
|
+
v-if="activeIndex === localPictures.length"
|
|
79
97
|
:src="videoSrc"
|
|
80
98
|
allowfullscreen
|
|
81
99
|
></iframe>
|
|
@@ -151,7 +169,7 @@
|
|
|
151
169
|
class="btn btn-success"
|
|
152
170
|
@click="buy"
|
|
153
171
|
>
|
|
154
|
-
<i class="
|
|
172
|
+
<i class="i-shopping-cart"></i>
|
|
155
173
|
<span class="d-none d-md-inline ml-1">
|
|
156
174
|
{{ i19addToCart }}
|
|
157
175
|
</span>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<portal :selector="`#${portalId}`">
|
|
2
|
+
<div class="product-quickview">
|
|
3
|
+
<a-backdrop
|
|
4
|
+
:is-visible="isVisible"
|
|
5
|
+
@hide="hide"
|
|
6
|
+
/>
|
|
7
|
+
|
|
8
|
+
<transition
|
|
9
|
+
enter-active-class="animated zoomIn"
|
|
10
|
+
leave-active-class="animated fadeOutUp slow"
|
|
11
|
+
>
|
|
12
|
+
<div
|
|
13
|
+
class="product-quickview__box card"
|
|
14
|
+
v-if="isVisible"
|
|
15
|
+
>
|
|
16
|
+
<slot name="header">
|
|
17
|
+
<div class="product-quickview__header card-header">
|
|
18
|
+
{{ productName }}
|
|
19
|
+
<button
|
|
20
|
+
type="button"
|
|
21
|
+
class="close"
|
|
22
|
+
:aria-label="i19close"
|
|
23
|
+
@click="hide"
|
|
24
|
+
>
|
|
25
|
+
<span aria-hidden="true">×</span>
|
|
26
|
+
</button>
|
|
27
|
+
</div>
|
|
28
|
+
</slot>
|
|
29
|
+
|
|
30
|
+
<div class="product-quickview__body card-body">
|
|
31
|
+
<div
|
|
32
|
+
v-if="!productName"
|
|
33
|
+
class="product-quickview__loading"
|
|
34
|
+
>
|
|
35
|
+
<div
|
|
36
|
+
class="spinner-border"
|
|
37
|
+
role="status"
|
|
38
|
+
>
|
|
39
|
+
<span class="sr-only">Loading...</span>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div class="container">
|
|
44
|
+
<the-product
|
|
45
|
+
is-quickview
|
|
46
|
+
:product-id="productId"
|
|
47
|
+
:product="product"
|
|
48
|
+
@update:product="setProduct"
|
|
49
|
+
@buy="hide"
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<a
|
|
54
|
+
v-if="productName"
|
|
55
|
+
class="product-quickview__btn-redirect btn btn-secondary"
|
|
56
|
+
:href="productLink"
|
|
57
|
+
>
|
|
58
|
+
{{ i19seeMoreInfo }}
|
|
59
|
+
</a>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</transition>
|
|
63
|
+
</div>
|
|
64
|
+
</portal>
|
|
@@ -4,18 +4,42 @@
|
|
|
4
4
|
>
|
|
5
5
|
<div
|
|
6
6
|
v-for="(options, grid, index) in variationsGrids"
|
|
7
|
+
v-if="filteredGrids[grid]"
|
|
7
8
|
:class="`variations__grid variations__grid--${grid}`"
|
|
8
9
|
>
|
|
9
|
-
<
|
|
10
|
+
<div class="mb-2">
|
|
11
|
+
<span class="variations__grid-title h5">
|
|
12
|
+
{{ getGridTitle(grid) }}
|
|
13
|
+
</span>
|
|
14
|
+
|
|
15
|
+
<span
|
|
16
|
+
v-if="selectedOptions[grid]"
|
|
17
|
+
key="success"
|
|
18
|
+
class="variations__value variations__value"
|
|
19
|
+
>
|
|
20
|
+
<i class="i-check mr-1"></i>
|
|
21
|
+
{{ selectedOptions[grid] }}
|
|
22
|
+
</span>
|
|
23
|
+
<span
|
|
24
|
+
v-else
|
|
25
|
+
class="variations__value variations__value--empty"
|
|
26
|
+
>
|
|
27
|
+
<i class="i-arrow-down mr-1"></i>
|
|
28
|
+
{{ i19selectVariation }}
|
|
29
|
+
</span>
|
|
30
|
+
</div>
|
|
10
31
|
|
|
11
32
|
<template v-if="options.length <= maxOptionsBtns">
|
|
12
33
|
<button
|
|
13
34
|
v-for="optionText in options"
|
|
14
35
|
class="variations__option btn btn-light"
|
|
15
|
-
:class="
|
|
36
|
+
:class="[
|
|
37
|
+
selectedOptions[grid] === optionText ? 'variations__option--selected' : null,
|
|
38
|
+
`variations__option--${optionText}`,
|
|
39
|
+
filteredGrids[grid].includes(optionText) ? null : 'disabled'
|
|
40
|
+
]"
|
|
16
41
|
:style="grid === 'colors' ? getColorOptionBg(optionText) : null"
|
|
17
42
|
@click="selectOption(optionText, grid, index)"
|
|
18
|
-
:disabled="!filteredGrids[grid].includes(optionText)"
|
|
19
43
|
>
|
|
20
44
|
{{ optionText }}
|
|
21
45
|
</button>
|
|
@@ -26,6 +50,9 @@
|
|
|
26
50
|
class="variations__select custom-select"
|
|
27
51
|
@change="$event => selectOption($event.target.value, grid, index)"
|
|
28
52
|
>
|
|
53
|
+
<option :selected="!selectedOptions[grid]">
|
|
54
|
+
{{ i19select }}...
|
|
55
|
+
</option>
|
|
29
56
|
<option
|
|
30
57
|
v-for="optionText in options"
|
|
31
58
|
:value="optionText"
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<div class="quantity-selector">
|
|
2
|
+
<div
|
|
3
|
+
class="quantity-selector__item"
|
|
4
|
+
v-for="item in items"
|
|
5
|
+
>
|
|
6
|
+
<div class="row quantity-selector__btn-container">
|
|
7
|
+
<button
|
|
8
|
+
class="btn btn-sm btn-link col-sm-3"
|
|
9
|
+
type="button"
|
|
10
|
+
@click="changeQnt(item, -1)"
|
|
11
|
+
:disabled="item.min_quantity >= selectedQnts[item._id]"
|
|
12
|
+
>
|
|
13
|
+
<i class="i-chevron-down"></i>
|
|
14
|
+
</button>
|
|
15
|
+
<input
|
|
16
|
+
type="tel"
|
|
17
|
+
class="form-control quantity-selector__input col-sm-6"
|
|
18
|
+
@change="ev => changeQnt(item, null, ev)"
|
|
19
|
+
@keyup.up="changeQnt(item, 1)"
|
|
20
|
+
@keyup.down="changeQnt(item, -1)"
|
|
21
|
+
:value="selectedQnts[item._id]"
|
|
22
|
+
:disabled="!checkInStock(item)"
|
|
23
|
+
:readonly="item.min_quantity && item.min_quantity === item.max_quantity"
|
|
24
|
+
>
|
|
25
|
+
<button
|
|
26
|
+
class="btn btn-sm btn-link col-sm-3"
|
|
27
|
+
type="button"
|
|
28
|
+
@click="changeQnt(item, 1)"
|
|
29
|
+
:disabled="item.max_quantity <= selectedQnts[item._id]"
|
|
30
|
+
>
|
|
31
|
+
<i class="i-chevron-up"></i>
|
|
32
|
+
</button>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<span class="quantity-selector__label">
|
|
36
|
+
<slot v-bind="{ item }">
|
|
37
|
+
<a-link
|
|
38
|
+
v-if="item.slug"
|
|
39
|
+
target="_blank"
|
|
40
|
+
:href="`/${item.slug}`"
|
|
41
|
+
:title="item.name"
|
|
42
|
+
>
|
|
43
|
+
{{ item.name }}
|
|
44
|
+
</a-link>
|
|
45
|
+
<template v-else>
|
|
46
|
+
{{ item.name }}
|
|
47
|
+
</template>
|
|
48
|
+
</slot>
|
|
49
|
+
</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<a-alert :can-show="hasMinAlert">
|
|
53
|
+
{{ i19minQuantity }}:
|
|
54
|
+
<strong>{{ min }}</strong>
|
|
55
|
+
</a-alert>
|
|
56
|
+
|
|
57
|
+
<a-alert
|
|
58
|
+
:can-show="hasMaxAlert"
|
|
59
|
+
:variant="alertVariant"
|
|
60
|
+
>
|
|
61
|
+
{{ i19maxQuantity }}:
|
|
62
|
+
<strong>{{ max }}</strong>
|
|
63
|
+
</a-alert>
|
|
64
|
+
|
|
65
|
+
<div
|
|
66
|
+
v-if="hasBuyButton"
|
|
67
|
+
class="quantity-selector__buy"
|
|
68
|
+
>
|
|
69
|
+
<slot
|
|
70
|
+
name="buy"
|
|
71
|
+
v-bind="{ selectedQnts, buy }"
|
|
72
|
+
>
|
|
73
|
+
<button
|
|
74
|
+
type="button"
|
|
75
|
+
class="btn btn-lg btn-primary my-3"
|
|
76
|
+
@click="buy"
|
|
77
|
+
>
|
|
78
|
+
<slot name="buy-button-content">
|
|
79
|
+
<i class="i-shopping-bag mr-1"></i>
|
|
80
|
+
{{ strBuy }}
|
|
81
|
+
</slot>
|
|
82
|
+
</button>
|
|
83
|
+
</slot>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<section class="recommended-items">
|
|
2
|
+
<transition enter-active-class="animated fadeIn">
|
|
3
|
+
<div v-if="items.length">
|
|
4
|
+
<div
|
|
5
|
+
v-if="!productIds.length"
|
|
6
|
+
class="recommended-items__title"
|
|
7
|
+
>
|
|
8
|
+
<slot name="title">
|
|
9
|
+
<p class="lead">
|
|
10
|
+
{{ i19weRecommendToYou }}
|
|
11
|
+
</p>
|
|
12
|
+
</slot>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div :class="rowClassName">
|
|
16
|
+
<div
|
|
17
|
+
v-for="item in items"
|
|
18
|
+
:key="item._id"
|
|
19
|
+
:class="colClassName"
|
|
20
|
+
>
|
|
21
|
+
<slot
|
|
22
|
+
name="item"
|
|
23
|
+
v-bind="{ item }"
|
|
24
|
+
>
|
|
25
|
+
<product-card
|
|
26
|
+
:product="item"
|
|
27
|
+
:is-loaded="true"
|
|
28
|
+
v-bind="productCardProps"
|
|
29
|
+
/>
|
|
30
|
+
</slot>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div
|
|
35
|
+
v-if="canLoadMore"
|
|
36
|
+
class="recommended-items__load-more"
|
|
37
|
+
>
|
|
38
|
+
<button
|
|
39
|
+
v-if="totalCount >= pageSize * (pageNumber + 1)"
|
|
40
|
+
class="btn btn-sm btn-outline-secondary"
|
|
41
|
+
@click="pageNumber++"
|
|
42
|
+
>
|
|
43
|
+
<i class="i-plus mr-1"></i> {{ i19seeMore }}
|
|
44
|
+
</button>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</transition>
|
|
48
|
+
</section>
|