@crm-market/template-shared 1.0.6 → 1.0.8
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/assets/scss/_variables.scss +3 -3
- package/assets/scss/components/_header.scss +1 -1
- package/assets/scss/style.css +4 -4
- package/components/AboutUs/StaticContent.vue +32 -0
- package/components/Cart/CartEmpty.vue +42 -0
- package/components/Cart/CartItem.vue +145 -0
- package/components/Cart/CartSummary.vue +57 -0
- package/components/Cart/ProductQuantity.vue +23 -13
- package/components/Cart/index.vue +68 -150
- package/components/Categories/index.vue +88 -291
- package/components/Checkout/AddressFields.vue +74 -0
- package/components/Checkout/CheckoutForm.vue +75 -0
- package/components/Checkout/CityAutocomplete.vue +68 -0
- package/components/Checkout/DeliveryMethodCard.vue +66 -0
- package/components/Checkout/DeliveryOptions.vue +148 -0
- package/components/Checkout/OrderSummary.vue +116 -0
- package/components/Checkout/PaymentOptions.vue +76 -0
- package/components/Checkout/PickupPoints.vue +46 -0
- package/components/Checkout/PromoCode.vue +166 -0
- package/components/Checkout/index.vue +235 -173
- package/components/Checkout/types.ts +45 -0
- package/components/Common/PageBanner.vue +22 -20
- package/components/Common/ProductCard.vue +139 -115
- package/components/Common/Services.vue +4 -4
- package/components/Contact/ContactForm.vue +44 -74
- package/components/Contact/ContactInfo.vue +35 -61
- package/components/FAQ/index.vue +6 -119
- package/components/Layout/Copyright.vue +11 -9
- package/components/Layout/Footer.vue +49 -136
- package/components/Layout/HeaderBar.vue +174 -0
- package/components/Layout/HeaderLogo.vue +27 -0
- package/components/Layout/MiddleHeader.vue +1 -228
- package/components/Layout/MiddleHeaderThree.vue +1 -203
- package/components/Layout/MiddleHeaderTwo.vue +1 -239
- package/components/Layout/NavLinks.vue +23 -0
- package/components/Layout/Navbar.vue +38 -151
- package/components/Layout/NavbarStyleFour.vue +1 -332
- package/components/Layout/NavbarStyleThree.vue +1 -188
- package/components/Layout/NavbarStyleTwo.vue +1 -108
- package/components/Layout/Preloader.vue +5 -12
- package/components/Layout/ResponsiveNavbar.vue +32 -418
- package/components/Layout/SitewideBanner.vue +285 -0
- package/components/Layout/TopHeader.vue +17 -83
- package/components/Layout/layoutData.ts +83 -0
- package/components/PrivacyPolicy/index.vue +6 -110
- package/components/ProductDetails/ProductDetailsTab.vue +31 -321
- package/components/ProductDetails/ProductGallery.vue +45 -0
- package/components/ProductDetails/ProductQuantity.vue +8 -14
- package/components/ProductDetails/RecentlyViewed.vue +53 -289
- package/components/ProductDetails/RelatedProducts.vue +64 -0
- package/components/ProductDetails/index.vue +90 -230
- package/components/Products/index.vue +78 -16
- package/components/TermsConditions/index.vue +6 -110
- package/components/Wishlist/index.vue +62 -88
- package/composables/useCart.ts +133 -81
- package/composables/useCategories.ts +67 -31
- package/composables/useCategoryImages.ts +45 -0
- package/composables/useCheckout.ts +302 -97
- package/composables/useContactForm.ts +57 -0
- package/composables/useHomeContent.ts +220 -0
- package/composables/useI18n.ts +12 -24
- package/composables/useJsonLd.ts +162 -0
- package/composables/useProducts.ts +244 -83
- package/composables/useRecent.ts +30 -0
- package/composables/useSanitize.ts +76 -0
- package/composables/useSiteConfig.ts +51 -47
- package/composables/useStaticPages.ts +48 -0
- package/composables/useStoreOrigin.ts +32 -0
- package/composables/useTemplateSections.ts +51 -3
- package/composables/useThemeVars.ts +113 -0
- package/composables/useWishlist.ts +72 -0
- package/layouts/default.vue +80 -19
- package/locales/en.json +255 -86
- package/locales/uk.json +251 -82
- package/modules/template-schema.ts +35 -0
- package/nuxt.config.ts +8 -11
- package/package.json +1 -1
- package/pages/about-us.vue +9 -9
- package/pages/cart.vue +0 -1
- package/pages/categories.vue +0 -1
- package/pages/category/[slug].vue +84 -0
- package/pages/checkout.vue +0 -1
- package/pages/contact.vue +6 -6
- package/pages/delivery.vue +12 -0
- package/pages/faq.vue +6 -6
- package/pages/order-success.vue +113 -0
- package/pages/privacy-policy.vue +6 -6
- package/pages/product/[slug].vue +82 -0
- package/pages/product-details.vue +14 -6
- package/pages/products.vue +12 -1
- package/pages/returns.vue +12 -0
- package/pages/terms-conditions.vue +6 -6
- package/pages/wishlist.vue +2 -2
- package/utils/image.ts +0 -1
- package/utils/seo-urls.ts +70 -0
- package/utils/store-origin.ts +36 -0
- package/components/AboutUs/AboutUsTuan.vue +0 -25
- package/components/AboutUs/Statistics.vue +0 -42
- package/components/AboutUs/SubscribeToTheNewsletter.vue +0 -57
- package/components/AddAddress/index.vue +0 -68
- package/components/BestSellers/Products.vue +0 -1562
- package/components/BestSellers/RecentlyViewed.vue +0 -304
- package/components/ChangePassword/index.vue +0 -69
- package/components/Common/DashboardNavigation.vue +0 -35
- package/components/Dashboard/RecentOrder.vue +0 -173
- package/components/Dashboard/index.vue +0 -77
- package/components/EditAddress/index.vue +0 -117
- package/components/EditProfile/index.vue +0 -95
- package/components/FeaturedProduct/FeaturedProducts.vue +0 -304
- package/components/FeaturedProduct/Products.vue +0 -1562
- package/components/ForgotPassword/index.vue +0 -49
- package/components/Layout/FooterTwo.vue +0 -159
- package/components/Layout/LocationOption.vue +0 -178
- package/components/Layout/RTLSwitchBtn.vue +0 -40
- package/components/Login/index.vue +0 -89
- package/components/MyAccount/index.vue +0 -154
- package/components/NewArrivals/Products.vue +0 -1969
- package/components/NewArrivals/RecentlyViewed.vue +0 -304
- package/components/OrderDetails/index.vue +0 -75
- package/components/OrderHistory/index.vue +0 -195
- package/components/Products/RecentlyViewed.vue +0 -302
- package/components/Register/index.vue +0 -83
- package/components/TrendingProducts/FeaturedProducts.vue +0 -304
- package/components/TrendingProducts/Products.vue +0 -1564
- package/components/Wishlist/ProductQuantity.vue +0 -29
- package/layouts/inner.vue +0 -70
- package/locales/ar.json +0 -234
- package/locales/ru.json +0 -234
- package/pages/address.vue +0 -11
- package/pages/change-password.vue +0 -11
- package/pages/dashboard.vue +0 -11
- package/pages/edit-address.vue +0 -11
- package/pages/edit-profile.vue +0 -11
- package/pages/forgot-password.vue +0 -11
- package/pages/login.vue +0 -11
- package/pages/my-account.vue +0 -11
- package/pages/order-details.vue +0 -11
- package/pages/order-history.vue +0 -11
- package/pages/register.vue +0 -11
|
@@ -1,304 +1,68 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="recently-viewed-area pb-60 products-page">
|
|
2
|
+
<div v-if="items.length" class="recently-viewed-area recently-viewed--compact pb-60 products-page">
|
|
3
3
|
<div class="container position-relative">
|
|
4
|
-
<div
|
|
5
|
-
class="
|
|
6
|
-
>
|
|
7
|
-
<h3 class="fs-3 mb-0 mb-1 mb-sm-0">Recently Viewed</h3>
|
|
4
|
+
<div class="d-lg-flex align-items-center justify-content-between text-center mb-27 mt-minus-6 border-top pt-4">
|
|
5
|
+
<h3 class="fs-3 mb-0 mb-1 mb-sm-0">{{ t('product.recentlyViewed') }}</h3>
|
|
8
6
|
<div>
|
|
9
7
|
<NuxtLink to="/products" class="read-more">
|
|
10
|
-
<span>
|
|
8
|
+
<span>{{ t('product.toCatalog') }}</span>
|
|
11
9
|
<i class="ri-arrow-right-up-line ms-1"></i>
|
|
12
10
|
</NuxtLink>
|
|
13
11
|
</div>
|
|
14
12
|
</div>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<NuxtLink to="/product-details" class="d-block">
|
|
20
|
-
<img src="~/assets/images/product-1.png" alt="product" />
|
|
21
|
-
</NuxtLink>
|
|
22
|
-
<div
|
|
23
|
-
class="d-flex justify-content-between align-items-center position-absolute top-0 start-0 end-0"
|
|
24
|
-
>
|
|
25
|
-
<span class="minus-count">-11%</span>
|
|
26
|
-
<button class="border-0 wish-btn">
|
|
27
|
-
<i class="ri-heart-line"></i>
|
|
28
|
-
<i class="ri-heart-fill d-none"></i>
|
|
29
|
-
<v-tooltip activator="parent" location="top">
|
|
30
|
-
Favorite
|
|
31
|
-
</v-tooltip>
|
|
32
|
-
</button>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
<div class="product-content">
|
|
36
|
-
<NuxtLink to="/product-details" class="title">
|
|
37
|
-
Microwave Oven With LED Lighting - 700 Watts, 0.7 cu ft
|
|
38
|
-
</NuxtLink>
|
|
39
|
-
<div class="d-flex gap-1 review">
|
|
40
|
-
<i class="flaticon-star"></i>
|
|
41
|
-
<i class="flaticon-star"></i>
|
|
42
|
-
<i class="flaticon-star"></i>
|
|
43
|
-
<i class="flaticon-star"></i>
|
|
44
|
-
<i class="flaticon-star"></i>
|
|
45
|
-
<span>(5 Reviews)</span>
|
|
46
|
-
</div>
|
|
47
|
-
<h3>$399 <del>$450</del></h3>
|
|
48
|
-
<div class="d-flex sold-stock gap-4 align-items-center">
|
|
49
|
-
<span class="sold">620 Sold</span>
|
|
50
|
-
<span class="stock">
|
|
51
|
-
<i class="ri-check-line"></i> 150 In Stock
|
|
52
|
-
</span>
|
|
53
|
-
</div>
|
|
54
|
-
<div
|
|
55
|
-
class="d-flex align-items-center justify-content-between delivery-cart gap-4"
|
|
56
|
-
>
|
|
57
|
-
<span class="delivery">
|
|
58
|
-
<i class="ri-truck-line"></i>
|
|
59
|
-
Free Delivery
|
|
60
|
-
</span>
|
|
61
|
-
<button class="cart-btn">
|
|
62
|
-
<i class="ri-shopping-cart-line"></i>
|
|
63
|
-
<v-tooltip activator="parent" location="top">
|
|
64
|
-
Add To Cart
|
|
65
|
-
</v-tooltip>
|
|
66
|
-
</button>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
<div class="col-c-20">
|
|
72
|
-
<div class="single-product-telemobile-item">
|
|
73
|
-
<div class="product-img position-relative">
|
|
74
|
-
<NuxtLink to="/product-details" class="d-block">
|
|
75
|
-
<img src="~/assets/images/product-6.png" alt="product" />
|
|
76
|
-
</NuxtLink>
|
|
77
|
-
<div
|
|
78
|
-
class="d-flex justify-content-between align-items-center position-absolute top-0 start-0 end-0"
|
|
79
|
-
>
|
|
80
|
-
<span class="minus-count">-15%</span>
|
|
81
|
-
<button class="border-0 wish-btn">
|
|
82
|
-
<i class="ri-heart-line"></i>
|
|
83
|
-
<i class="ri-heart-fill d-none"></i>
|
|
84
|
-
<v-tooltip activator="parent" location="top">
|
|
85
|
-
Favorite
|
|
86
|
-
</v-tooltip>
|
|
87
|
-
</button>
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
<div class="product-content">
|
|
91
|
-
<NuxtLink to="/product-details" class="title">
|
|
92
|
-
Multiplatform Wireless Noise-Cancelling Gaming Headset
|
|
93
|
-
</NuxtLink>
|
|
94
|
-
<div class="d-flex gap-1 review">
|
|
95
|
-
<i class="flaticon-star"></i>
|
|
96
|
-
<i class="flaticon-star"></i>
|
|
97
|
-
<i class="flaticon-star"></i>
|
|
98
|
-
<i class="flaticon-star"></i>
|
|
99
|
-
<i class="flaticon-star"></i>
|
|
100
|
-
<span>(18 Reviews)</span>
|
|
101
|
-
</div>
|
|
102
|
-
<h3>$279 <del>$329</del></h3>
|
|
103
|
-
<div class="d-flex sold-stock gap-4 align-items-center">
|
|
104
|
-
<span class="sold">20 Sold</span>
|
|
105
|
-
<span class="stock">
|
|
106
|
-
<i class="ri-check-line"></i>
|
|
107
|
-
78 In Stock
|
|
108
|
-
</span>
|
|
109
|
-
</div>
|
|
110
|
-
<div
|
|
111
|
-
class="d-flex align-items-center justify-content-between delivery-cart gap-4"
|
|
112
|
-
>
|
|
113
|
-
<span class="delivery">
|
|
114
|
-
<i class="ri-truck-line"></i>
|
|
115
|
-
Free Delivery
|
|
116
|
-
</span>
|
|
117
|
-
<button class="cart-btn">
|
|
118
|
-
<i class="ri-shopping-cart-line"></i>
|
|
119
|
-
<v-tooltip activator="parent" location="top">
|
|
120
|
-
Add To Cart
|
|
121
|
-
</v-tooltip>
|
|
122
|
-
</button>
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
<div class="col-c-20">
|
|
128
|
-
<div class="single-product-telemobile-item">
|
|
129
|
-
<div class="product-img position-relative">
|
|
130
|
-
<NuxtLink to="/product-details" class="d-block">
|
|
131
|
-
<img src="~/assets/images/product-7.png" alt="product" />
|
|
132
|
-
</NuxtLink>
|
|
133
|
-
<div
|
|
134
|
-
class="d-flex justify-content-between align-items-center position-absolute top-0 start-0 end-0"
|
|
135
|
-
>
|
|
136
|
-
<span class="minus-count">-40%</span>
|
|
137
|
-
<button class="border-0 wish-btn">
|
|
138
|
-
<i class="ri-heart-line"></i>
|
|
139
|
-
<i class="ri-heart-fill d-none"></i>
|
|
140
|
-
<v-tooltip activator="parent" location="top">
|
|
141
|
-
Favorite
|
|
142
|
-
</v-tooltip>
|
|
143
|
-
</button>
|
|
144
|
-
</div>
|
|
145
|
-
</div>
|
|
146
|
-
<div class="product-content">
|
|
147
|
-
<NuxtLink to="/product-details" class="title">
|
|
148
|
-
GPS Smartwatch with Bright Touchscreen Display
|
|
149
|
-
</NuxtLink>
|
|
150
|
-
<div class="d-flex gap-1 review">
|
|
151
|
-
<i class="flaticon-star"></i>
|
|
152
|
-
<i class="flaticon-star"></i>
|
|
153
|
-
<i class="flaticon-star"></i>
|
|
154
|
-
<i class="flaticon-star"></i>
|
|
155
|
-
<i class="flaticon-star"></i>
|
|
156
|
-
<span>(24 Reviews)</span>
|
|
157
|
-
</div>
|
|
158
|
-
<h3>$119 <del>$199</del></h3>
|
|
159
|
-
<div class="d-flex sold-stock gap-4 align-items-center">
|
|
160
|
-
<span class="sold">435 Sold</span>
|
|
161
|
-
<span class="stock">
|
|
162
|
-
<i class="ri-check-line"></i>
|
|
163
|
-
180 In Stock
|
|
164
|
-
</span>
|
|
165
|
-
</div>
|
|
166
|
-
<div
|
|
167
|
-
class="d-flex align-items-center justify-content-between delivery-cart gap-4"
|
|
168
|
-
>
|
|
169
|
-
<span class="delivery">
|
|
170
|
-
<i class="ri-truck-line"></i>
|
|
171
|
-
Free Delivery
|
|
172
|
-
</span>
|
|
173
|
-
<button class="cart-btn">
|
|
174
|
-
<i class="ri-shopping-cart-line"></i>
|
|
175
|
-
<v-tooltip activator="parent" location="top">
|
|
176
|
-
Add To Cart
|
|
177
|
-
</v-tooltip>
|
|
178
|
-
</button>
|
|
179
|
-
</div>
|
|
180
|
-
</div>
|
|
181
|
-
</div>
|
|
182
|
-
</div>
|
|
183
|
-
<div class="col-c-20">
|
|
184
|
-
<div class="single-product-telemobile-item">
|
|
185
|
-
<div class="product-img position-relative">
|
|
186
|
-
<NuxtLink to="/product-details" class="d-block">
|
|
187
|
-
<img src="~/assets/images/product-8.png" alt="product" />
|
|
188
|
-
</NuxtLink>
|
|
189
|
-
<div
|
|
190
|
-
class="d-flex justify-content-between align-items-center position-absolute top-0 start-0 end-0"
|
|
191
|
-
>
|
|
192
|
-
<span class="minus-count">-20%</span>
|
|
193
|
-
<button class="border-0 wish-btn">
|
|
194
|
-
<i class="ri-heart-line"></i>
|
|
195
|
-
<i class="ri-heart-fill d-none"></i>
|
|
196
|
-
<v-tooltip activator="parent" location="top">
|
|
197
|
-
Favorite
|
|
198
|
-
</v-tooltip>
|
|
199
|
-
</button>
|
|
200
|
-
</div>
|
|
201
|
-
</div>
|
|
202
|
-
<div class="product-content">
|
|
203
|
-
<NuxtLink to="/product-details" class="title">
|
|
204
|
-
SAMSUNG 32-Inch Class QLED 4K Q60C Series Quantum HDR
|
|
205
|
-
</NuxtLink>
|
|
206
|
-
<div class="d-flex gap-1 review">
|
|
207
|
-
<i class="flaticon-star"></i>
|
|
208
|
-
<i class="flaticon-star"></i>
|
|
209
|
-
<i class="flaticon-star"></i>
|
|
210
|
-
<i class="flaticon-star"></i>
|
|
211
|
-
<i class="flaticon-star"></i>
|
|
212
|
-
<span>(19 Reviews)</span>
|
|
213
|
-
</div>
|
|
214
|
-
<h3>$397 <del>$497</del></h3>
|
|
215
|
-
<div class="d-flex sold-stock gap-4 align-items-center">
|
|
216
|
-
<span class="sold">35 Sold</span>
|
|
217
|
-
<span class="stock">
|
|
218
|
-
<i class="ri-check-line"></i>
|
|
219
|
-
125 In Stock
|
|
220
|
-
</span>
|
|
221
|
-
</div>
|
|
222
|
-
<div
|
|
223
|
-
class="d-flex align-items-center justify-content-between delivery-cart gap-4"
|
|
224
|
-
>
|
|
225
|
-
<span class="delivery">
|
|
226
|
-
<i class="ri-truck-line"></i>
|
|
227
|
-
Free Delivery
|
|
228
|
-
</span>
|
|
229
|
-
<button class="cart-btn">
|
|
230
|
-
<i class="ri-shopping-cart-line"></i>
|
|
231
|
-
<v-tooltip activator="parent" location="top">
|
|
232
|
-
Add To Cart
|
|
233
|
-
</v-tooltip>
|
|
234
|
-
</button>
|
|
235
|
-
</div>
|
|
236
|
-
</div>
|
|
237
|
-
</div>
|
|
238
|
-
</div>
|
|
239
|
-
<div class="col-c-20">
|
|
240
|
-
<div class="single-product-telemobile-item">
|
|
241
|
-
<div class="product-img position-relative">
|
|
242
|
-
<NuxtLink to="/product-details" class="d-block">
|
|
243
|
-
<img src="~/assets/images/product-9.png" alt="product" />
|
|
244
|
-
</NuxtLink>
|
|
245
|
-
<div
|
|
246
|
-
class="d-flex justify-content-between align-items-center position-absolute top-0 start-0 end-0"
|
|
247
|
-
>
|
|
248
|
-
<span class="minus-count">-10%</span>
|
|
249
|
-
<button class="border-0 wish-btn">
|
|
250
|
-
<i class="ri-heart-line"></i>
|
|
251
|
-
<i class="ri-heart-fill d-none"></i>
|
|
252
|
-
<v-tooltip activator="parent" location="top">
|
|
253
|
-
Favorite
|
|
254
|
-
</v-tooltip>
|
|
255
|
-
</button>
|
|
256
|
-
</div>
|
|
257
|
-
</div>
|
|
258
|
-
<div class="product-content">
|
|
259
|
-
<NuxtLink to="/product-details" class="title">
|
|
260
|
-
Apple MacBook Pro 16.2" with Liquid Retina XDR Display
|
|
261
|
-
</NuxtLink>
|
|
262
|
-
<div class="d-flex gap-1 review">
|
|
263
|
-
<i class="flaticon-star"></i>
|
|
264
|
-
<i class="flaticon-star"></i>
|
|
265
|
-
<i class="flaticon-star"></i>
|
|
266
|
-
<i class="flaticon-star"></i>
|
|
267
|
-
<i class="flaticon-star"></i>
|
|
268
|
-
<span>(76 Reviews)</span>
|
|
269
|
-
</div>
|
|
270
|
-
<h3>$3,499 <del>$3,799</del></h3>
|
|
271
|
-
<div class="d-flex sold-stock gap-4 align-items-center">
|
|
272
|
-
<span class="sold">348 Sold</span>
|
|
273
|
-
<span class="stock">
|
|
274
|
-
<i class="ri-check-line"></i>
|
|
275
|
-
245 In Stock
|
|
276
|
-
</span>
|
|
277
|
-
</div>
|
|
278
|
-
<div
|
|
279
|
-
class="d-flex align-items-center justify-content-between delivery-cart gap-4"
|
|
280
|
-
>
|
|
281
|
-
<span class="delivery">
|
|
282
|
-
<i class="ri-truck-line"></i>
|
|
283
|
-
Free Delivery
|
|
284
|
-
</span>
|
|
285
|
-
<button class="cart-btn">
|
|
286
|
-
<i class="ri-shopping-cart-line"></i>
|
|
287
|
-
<v-tooltip activator="parent" location="top">
|
|
288
|
-
Add To Cart
|
|
289
|
-
</v-tooltip>
|
|
290
|
-
</button>
|
|
291
|
-
</div>
|
|
292
|
-
</div>
|
|
293
|
-
</div>
|
|
13
|
+
<!-- Компактні картки: 6 у ряд на десктопі, менші відступи й шрифти -->
|
|
14
|
+
<div class="row g-3">
|
|
15
|
+
<div v-for="item in items" :key="item.id" class="col-6 col-md-4 col-lg-2">
|
|
16
|
+
<CommonProductCard :product="item" />
|
|
294
17
|
</div>
|
|
295
18
|
</div>
|
|
296
19
|
</div>
|
|
297
20
|
</div>
|
|
298
21
|
</template>
|
|
299
22
|
|
|
300
|
-
<script>
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
23
|
+
<script setup lang="ts">
|
|
24
|
+
import { onMounted, ref } from 'vue';
|
|
25
|
+
import type { Product } from '../../composables/useProducts';
|
|
26
|
+
|
|
27
|
+
// Поточний товар не показуємо серед нещодавніх
|
|
28
|
+
const props = defineProps<{ currentId?: string }>();
|
|
29
|
+
|
|
30
|
+
const { t } = useI18n();
|
|
31
|
+
const { ids, load } = useRecent();
|
|
32
|
+
const { fetchProductsByIds } = useProducts();
|
|
33
|
+
|
|
34
|
+
const items = ref<Product[]>([]);
|
|
35
|
+
|
|
36
|
+
onMounted(async () => {
|
|
37
|
+
load();
|
|
38
|
+
const list = ids.value.filter((id) => id !== props.currentId);
|
|
39
|
+
if (list.length) items.value = await fetchProductsByIds(list);
|
|
40
|
+
});
|
|
304
41
|
</script>
|
|
42
|
+
|
|
43
|
+
<style scoped>
|
|
44
|
+
/* Зменшені картки «Нещодавно переглянуті» (стилі картки — у дочірньому компоненті, тому :deep) */
|
|
45
|
+
.recently-viewed--compact :deep(.single-product-telemobile-item) {
|
|
46
|
+
padding: 10px;
|
|
47
|
+
}
|
|
48
|
+
.recently-viewed--compact :deep(.single-product-telemobile-item img) {
|
|
49
|
+
max-height: 140px;
|
|
50
|
+
object-fit: cover;
|
|
51
|
+
}
|
|
52
|
+
.recently-viewed--compact :deep(.single-product-telemobile-item h3),
|
|
53
|
+
.recently-viewed--compact :deep(.single-product-telemobile-item .title) {
|
|
54
|
+
font-size: 13px;
|
|
55
|
+
line-height: 1.3;
|
|
56
|
+
}
|
|
57
|
+
.recently-viewed--compact :deep(.single-product-telemobile-item .price),
|
|
58
|
+
.recently-viewed--compact :deep(.single-product-telemobile-item .fs-5) {
|
|
59
|
+
font-size: 14px !important;
|
|
60
|
+
}
|
|
61
|
+
.recently-viewed--compact :deep(.single-product-telemobile-item .btn) {
|
|
62
|
+
padding: 4px 10px;
|
|
63
|
+
font-size: 12px;
|
|
64
|
+
}
|
|
65
|
+
.recently-viewed--compact :deep(.wish-btn) {
|
|
66
|
+
transform: scale(0.85);
|
|
67
|
+
}
|
|
68
|
+
</style>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import type { Product } from '../../composables/useProducts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* «Схожі товари»: товари з тієї ж категорії, без поточного.
|
|
7
|
+
* Якщо в категорії нічого немає — рекомендовані (featured) товари магазину.
|
|
8
|
+
*/
|
|
9
|
+
const props = defineProps<{ product: Product }>();
|
|
10
|
+
const { t } = useI18n();
|
|
11
|
+
const { fetchByCategory, fetchFeatured } = useProducts();
|
|
12
|
+
|
|
13
|
+
const LIMIT = 6;
|
|
14
|
+
const categoryId = computed(() => props.product.categories?.[0]?.id || '');
|
|
15
|
+
|
|
16
|
+
const { data: items } = await useAsyncData(
|
|
17
|
+
`related-${props.product.id}`,
|
|
18
|
+
async () => {
|
|
19
|
+
let list: Product[] = [];
|
|
20
|
+
if (categoryId.value) {
|
|
21
|
+
list = await fetchByCategory(categoryId.value, LIMIT + 1).catch(() => []);
|
|
22
|
+
}
|
|
23
|
+
list = list.filter((p) => p.id !== props.product.id);
|
|
24
|
+
if (list.length < 3) {
|
|
25
|
+
const featured = await fetchFeatured(LIMIT + 1).catch(() => []);
|
|
26
|
+
const ids = new Set(list.map((p) => p.id));
|
|
27
|
+
list = [...list, ...featured.filter((p) => p.id !== props.product.id && !ids.has(p.id))];
|
|
28
|
+
}
|
|
29
|
+
return list.slice(0, LIMIT);
|
|
30
|
+
},
|
|
31
|
+
{ default: () => [] as Product[], watch: [() => props.product.id] },
|
|
32
|
+
);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<div v-if="items.length" class="related-products-area related-products--compact pb-60 products-page">
|
|
37
|
+
<div class="container">
|
|
38
|
+
<div class="d-lg-flex align-items-center justify-content-between text-center mb-27 border-top pt-4">
|
|
39
|
+
<h3 class="fs-3 mb-0 mb-1 mb-sm-0">{{ t('product.related') }}</h3>
|
|
40
|
+
<NuxtLink v-if="categoryId && product.categories?.length" :to="categoryPath(product.categories[0])" class="read-more">
|
|
41
|
+
<span>{{ t('product.moreInCategory') }}</span>
|
|
42
|
+
<i class="ri-arrow-right-up-line ms-1"></i>
|
|
43
|
+
</NuxtLink>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="row g-3">
|
|
46
|
+
<div v-for="item in items" :key="item.id" class="col-6 col-md-4 col-lg-2">
|
|
47
|
+
<CommonProductCard :product="item" />
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<style scoped>
|
|
55
|
+
/* Компактні картки, як у «Нещодавно переглянуті» */
|
|
56
|
+
.related-products--compact :deep(.single-product-telemobile-item) { padding: 10px; }
|
|
57
|
+
.related-products--compact :deep(.single-product-telemobile-item img) { max-height: 140px; object-fit: cover; }
|
|
58
|
+
.related-products--compact :deep(.single-product-telemobile-item h3),
|
|
59
|
+
.related-products--compact :deep(.single-product-telemobile-item .title) { font-size: 13px; line-height: 1.3; }
|
|
60
|
+
.related-products--compact :deep(.single-product-telemobile-item .price),
|
|
61
|
+
.related-products--compact :deep(.single-product-telemobile-item .fs-5) { font-size: 14px !important; }
|
|
62
|
+
.related-products--compact :deep(.single-product-telemobile-item .btn) { padding: 4px 10px; font-size: 12px; }
|
|
63
|
+
.related-products--compact :deep(.wish-btn) { transform: scale(0.85); }
|
|
64
|
+
</style>
|