@meeovi/layer-commerce 1.0.2 → 1.0.4

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 (58) hide show
  1. package/app/components/catalog/product/ProductAccordion/types.ts +3 -3
  2. package/app/components/catalog/product/ProductProperties/types.ts +3 -3
  3. package/app/components/catalog/product/ProductSlider/types.ts +5 -5
  4. package/app/components/catalog/product/RecommendedProducts/types.ts +3 -3
  5. package/app/components/catalog/product/bestsellers.vue +8 -20
  6. package/app/components/catalog/product/deals.vue +7 -22
  7. package/app/components/catalog/product/exclusives.vue +8 -10
  8. package/app/components/catalog/product/featuredproducts.vue +8 -20
  9. package/app/components/catalog/product/latestproducts.vue +8 -20
  10. package/app/components/catalog/product/productCard.vue +55 -21
  11. package/app/components/catalog/product/productDetails.vue +20 -14
  12. package/app/components/catalog/product/relatedproducts.vue +5 -20
  13. package/app/components/catalog/product/sizeOptions.vue +3 -8
  14. package/app/components/catalog/shops/relatedstores.vue +6 -21
  15. package/app/components/categories/chart/[id].vue +200 -0
  16. package/app/components/categories/chart/add-chart.vue +142 -0
  17. package/app/components/categories/chart/chart.vue +82 -0
  18. package/app/components/categories/chart/monthlyChart.vue +46 -0
  19. package/app/components/categories/chart/weeklyChart.vue +46 -0
  20. package/app/components/categories/chart/yearlyChart.vue +46 -0
  21. package/app/components/categories/charts.vue +118 -0
  22. package/app/components/categories/deals.vue +101 -0
  23. package/app/components/categories/eats.vue +49 -0
  24. package/app/components/categories/restaurants.vue +26 -0
  25. package/app/components/categories/station/[id].vue +72 -0
  26. package/app/components/categories/stations.vue +124 -0
  27. package/app/components/categories/time/time.vue +63 -0
  28. package/app/components/categories/travel.vue +75 -0
  29. package/app/components/categories/weather/weather.vue +44 -0
  30. package/app/components/content/pages/showcases.vue +1 -1
  31. package/app/components/marketing/promotions/giftcards.vue +20 -45
  32. package/app/components/marketing/promotions/subscriptions.vue +8 -21
  33. package/app/components/placeholders/Comments.vue +15 -0
  34. package/app/components/placeholders/CreateListBtn.vue +7 -0
  35. package/app/components/placeholders/Event.vue +9 -0
  36. package/app/components/placeholders/ListShowcases.vue +9 -0
  37. package/app/components/placeholders/Short.vue +9 -0
  38. package/app/components/placeholders/Space.vue +9 -0
  39. package/app/components/placeholders/Tag.vue +7 -0
  40. package/app/components/sales/CheckoutAddress/types.ts +12 -11
  41. package/app/components/sales/OrderSummary/types.ts +3 -3
  42. package/app/components/sales/incentives.vue +13 -37
  43. package/app/composables/cart/registry.ts +7 -0
  44. package/app/composables/index.ts +1 -0
  45. package/app/composables/products/registry.ts +7 -0
  46. package/app/composables/registry.ts +21 -0
  47. package/app/composables/useCatalog.ts +64 -0
  48. package/app/composables/useContent.ts +57 -0
  49. package/app/composables/useProducts/types.ts +15 -10
  50. package/app/pages/brand/[...slug].vue +1 -1
  51. package/app/pages/departments/[...slug].vue +385 -0
  52. package/app/pages/departments/category/[...slug].vue +135 -0
  53. package/app/pages/product/[...id].vue +3 -3
  54. package/app/pages/shop/[...slug].vue +12 -18
  55. package/app/pages/shops.vue +18 -25
  56. package/global.d.ts +14 -0
  57. package/package.json +4 -2
  58. package/tsconfig.json +10 -1
@@ -0,0 +1,385 @@
1
+ <template>
2
+ <div>
3
+ <div v-if="department?.name === 'Deals'">
4
+ <v-toolbar :style="`background-color: ${department?.color}; color: ${department?.colortext}`"
5
+ :title="department?.name"></v-toolbar>
6
+ <deals :category="department?.id" />
7
+ </div>
8
+
9
+ <div v-else>
10
+ <v-card variant="text">
11
+ <v-toolbar :style="`background-color: ${department?.color}; color: ${department?.colortext}`"
12
+ :title="department?.name">
13
+ <v-slide-group show-arrows v-if="department?.categories?.length">
14
+ <v-slide-group-item v-slot="{ isSelected, toggle }">
15
+ <v-menu>
16
+ <template v-slot:activator="{ props }">
17
+ <v-btn :color="isSelected ? 'primary' : undefined" class="ma-2" @click="toggle"
18
+ v-bind="props" append-icon="fas:fa fa-caret-down" variant="text">
19
+ Categories
20
+ </v-btn>
21
+ </template>
22
+ <v-list class="departmentMenu">
23
+ <v-row>
24
+ <v-col cols="3" v-for="categories in department?.categories"
25
+ :key="categories?.id">
26
+ <v-list-item>
27
+ <v-chip><NuxtLink
28
+ :to="`/departments/category/${categories?.categories_id?.slug}`">
29
+ {{ categories?.categories_id?.name }}</NuxtLink></v-chip>
30
+ </v-list-item>
31
+ </v-col>
32
+ </v-row>
33
+ </v-list>
34
+ </v-menu>
35
+ </v-slide-group-item>
36
+
37
+ <v-slide-group-item v-if="department?.menus?.length" v-for="menu in department?.menus"
38
+ :key="menu" v-slot="{ isSelected, toggle }">
39
+ <v-btn :color="isSelected ? 'primary' : undefined" class="ma-2" @click="toggle"
40
+ :href="`${menu?.url}`">
41
+ {{ menu?.name }}
42
+ </v-btn>
43
+ </v-slide-group-item>
44
+ </v-slide-group>
45
+ </v-toolbar>
46
+
47
+ <!--Department Top Banner Section-->
48
+ <section data-bs-version="5.1" class="pricing6 shopm5 cid-tZY31Y2JxZ" id="apricing6-6g">
49
+
50
+ <div class="mbr-overlay"></div>
51
+ <div class="container-fluid">
52
+ <div class="row align-items-stretch items-row justify-content-center">
53
+
54
+ <div class="col-lg-6">
55
+ <div v-if="department?.name === 'Travel'">
56
+ <travel :category="department?.name" />
57
+ </div>
58
+ <!--<div v-else-if="department?.name === 'Appstore'">
59
+ <appstore :category="department?.name" />
60
+ </div>-->
61
+ <div v-else-if="department?.name === 'Weather'">
62
+ <weather :category="department?.name" />
63
+ </div>
64
+
65
+ <div v-else-if="department?.name === 'Time'">
66
+ <timeComponent :category="department?.name" />
67
+ </div>
68
+
69
+ <div v-else class="mbr-section-head" :style="`background-color: ${department?.color}`">
70
+ <h4 class="mbr-section-title mbr-fonts-style mb-0 display-7"
71
+ :style="`color: ${department?.colortext}`">
72
+ <strong>Meeovi</strong>
73
+ </h4>
74
+ <h5 class="mbr-section-subtitle mbr-fonts-style mb-0 display-2"
75
+ :style="`color: ${department?.colortext}`">
76
+ <strong>{{ department?.name }}</strong>
77
+ </h5>
78
+ <h5 class="main-text mbr-fonts-style mb-0 display-7"
79
+ :style="`color: ${department?.colortext}`">
80
+ {{ department?.description }}
81
+ </h5>
82
+ </div>
83
+ </div>
84
+
85
+ <v-sheet
86
+ class="mx-auto col-lg-6" style="background-color: transparent; box-shadow: none;">
87
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[1]?.name }}</h4>
88
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
89
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
90
+ v-for="products in department?.products" :key="products">
91
+ <productCard :product="products?.products_id" :class="['ma-4', selectedClass]"
92
+ @click="toggle" />
93
+ <div class="d-flex fill-height align-center justify-center">
94
+ <v-scale-transition>
95
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
96
+ size="48"></v-icon>
97
+ </v-scale-transition>
98
+ </div>
99
+ </v-slide-group-item>
100
+ </v-slide-group>
101
+ </v-sheet>
102
+ </div>
103
+ </div>
104
+ </section>
105
+
106
+ <!--Department Content Section-->
107
+ <section data-bs-version="5.1" class="gallery2 shopm5 cid-uW1BojE78S" id="agallery2-0" v-if="department?.shorts?.length && department?.products?.products_id?.type === 'department'"
108
+ :style="`background-image: url(${$directus?.url}assets/${department?.image?.filename_disk})`">
109
+ <div class="mbr-overlay" style="opacity: 0.8; background-color: rgb(255, 255, 255);">
110
+ </div>
111
+
112
+ <div class="container-fluid">
113
+ <div class="row">
114
+ <!--Vibez Slider-->
115
+ <v-sheet
116
+ class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center">
117
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
118
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
119
+ v-for="shorts in department?.shorts" :key="shorts">
120
+ <shorts :short="shorts?.shorts_id" :class="['ma-4', selectedClass]"
121
+ @click="toggle" />
122
+ <div class="d-flex fill-height align-center justify-center">
123
+ <v-scale-transition>
124
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
125
+ size="48"></v-icon>
126
+ </v-scale-transition>
127
+ </div>
128
+ </v-slide-group-item>
129
+ </v-slide-group>
130
+ </v-sheet>
131
+ </div>
132
+ </div>
133
+ </section>
134
+
135
+ <v-row class="departmentRow">
136
+ <!--Best Seller Product Slider-->
137
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center">
138
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[1]?.name }}</h4>
139
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
140
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
141
+ v-for="products in best?.products" :key="products">
142
+ <productCard :product="products?.products_id" :class="['ma-4', selectedClass]"
143
+ @click="toggle" />
144
+ <div class="d-flex fill-height align-center justify-center">
145
+ <v-scale-transition>
146
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
147
+ size="48"></v-icon>
148
+ </v-scale-transition>
149
+ </div>
150
+ </v-slide-group-item>
151
+ </v-slide-group>
152
+ </v-sheet>
153
+
154
+ <!--List of latest products in the department-->
155
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center">
156
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[2]?.name }}</h4>
157
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
158
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
159
+ v-for="products in latestProducts?.products" :key="products">
160
+ <productCard :product="products?.products_id" :class="['ma-4', selectedClass]"
161
+ @click="toggle" />
162
+ <div class="d-flex fill-height align-center justify-center">
163
+ <v-scale-transition>
164
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
165
+ size="48"></v-icon>
166
+ </v-scale-transition>
167
+ </div>
168
+ </v-slide-group-item>
169
+ </v-slide-group>
170
+ </v-sheet>
171
+
172
+ <!--List of products in the department-->
173
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center">
174
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
175
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
176
+ v-for="products in department?.products" :key="products">
177
+ <productCard :product="products?.products_id" :class="['ma-4', selectedClass]"
178
+ @click="toggle" />
179
+ <div class="d-flex fill-height align-center justify-center">
180
+ <v-scale-transition>
181
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
182
+ size="48"></v-icon>
183
+ </v-scale-transition>
184
+ </div>
185
+ </v-slide-group-item>
186
+ </v-slide-group>
187
+ </v-sheet>
188
+
189
+ <!--List of events in this department-->
190
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center"
191
+ v-if="department?.products?.products_id?.type === 'department' && events?.length">
192
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[3]?.name }}
193
+ {{ department?.name }}</h4>
194
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
195
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
196
+ v-for="products in events" :key="products">
197
+ <productCard :product="products?.events_id" :class="['ma-4', selectedClass]"
198
+ @click="toggle" />
199
+ <div class="d-flex fill-height align-center justify-center">
200
+ <v-scale-transition>
201
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
202
+ size="48"></v-icon>
203
+ </v-scale-transition>
204
+ </div>
205
+ </v-slide-group-item>
206
+ </v-slide-group>
207
+ </v-sheet>
208
+ <!---->
209
+
210
+ <!--List of spaces in the department-->
211
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center"
212
+ v-if="department?.spaces?.length">
213
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[4]?.name }}
214
+ {{ department?.name }}</h4>
215
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
216
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
217
+ v-for="spaces in department?.spaces" :key="spaces">
218
+ <spaces :space="spaces?.spaces_id" :class="['ma-4', selectedClass]" @click="toggle" />
219
+ <div class="d-flex fill-height align-center justify-center">
220
+ <v-scale-transition>
221
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
222
+ size="48"></v-icon>
223
+ </v-scale-transition>
224
+ </div>
225
+ </v-slide-group-item>
226
+ </v-slide-group>
227
+ </v-sheet>
228
+ </v-row>
229
+ </v-card>
230
+ </div>
231
+ </div>
232
+ </template>
233
+
234
+ <script setup>
235
+ import shorts from '#social/app/components/related/short.vue'
236
+ import spaces from '#social/app/components/related/space.vue'
237
+ import productCard from '#commerce/app/components/catalog/product/productCard.vue'
238
+ import travel from '@/components/categories/travel.vue'
239
+ import deals from '@/components/categories/deals.vue'
240
+ import timeComponent from '@/components/categories/time/time.vue'
241
+ import weather from '@/components/categories/weather/weather.vue'
242
+
243
+ const route = useRoute()
244
+ const model = ref(null)
245
+ const {
246
+ $directus,
247
+ $readItem,
248
+ $readItems
249
+ } = useNuxtApp()
250
+
251
+ const slug = computed(() => {
252
+ const s = route.params.slug
253
+ return Array.isArray(s) ? s[0] : s
254
+ })
255
+
256
+ const {
257
+ data: departmentRaw
258
+ } = await useAsyncData('department', () => {
259
+ return $directus.request(
260
+ $readItems('departments', {
261
+ fields: [
262
+ '*',
263
+ 'categories.categories_id.*',
264
+ 'spaces.spaces_id.*',
265
+ 'products.products_id.*',
266
+ 'products.products_id.image.*',
267
+ 'shorts.shorts_id.*',
268
+ 'shops.shops_id.*',
269
+ 'image.*'
270
+ ],
271
+ filter: {
272
+ slug: {
273
+ _eq: slug.value
274
+ }
275
+ },
276
+ limit: 1
277
+ })
278
+ )
279
+ })
280
+
281
+ const department = computed(() => departmentRaw.value?.[0] || null)
282
+
283
+ const {
284
+ data: introProducts
285
+ } = await useAsyncData('introProducts', () => {
286
+ return $directus.request($readItems('departments', {
287
+ fields: ['*', { '*': ['*'] }],
288
+ limit: 2,
289
+ }))
290
+ })
291
+
292
+ const {
293
+ data: best
294
+ } = await useAsyncData('best', () => {
295
+ return $directus.request($readItems('departments', {
296
+ fields: ['*',
297
+ 'products.products_id.*',
298
+ 'images.*'
299
+ ],
300
+ limit: 10,
301
+ filter: {
302
+ showcases: {
303
+ showcases_id: {
304
+ name: {
305
+ _eq: "Best Sellers"
306
+ }
307
+ }
308
+ },
309
+ }
310
+ }))
311
+ })
312
+
313
+ const {
314
+ data: latestProducts
315
+ } = await useAsyncData('latestProducts', () => {
316
+ return $directus.request($readItems('departments', {
317
+ fields: ['*',
318
+ 'products.products_id.*',
319
+ 'images.*'
320
+ ],
321
+ limit: 10,
322
+ filter: {
323
+ products: {
324
+ products_id: {
325
+ status: {
326
+ _eq: "published"
327
+ }
328
+ }
329
+ },
330
+ }
331
+ }))
332
+ })
333
+
334
+ const {
335
+ data: limitProducts
336
+ } = await useAsyncData('limitProducts', () => {
337
+ return $directus.request($readItems('departments', {
338
+ fields: ['*',
339
+ 'products.products_id.*',
340
+ 'images.*'
341
+ ],
342
+ limit: 2,
343
+ filter: {
344
+ products: {
345
+ products_id: {
346
+ status: {
347
+ _eq: "published"
348
+ }
349
+ }
350
+ },
351
+ }
352
+ }))
353
+ })
354
+
355
+ const {
356
+ data: events
357
+ } = await useAsyncData('events', () => {
358
+ return $directus.request($readItems('departments', {
359
+ fields: ['*',
360
+ 'products.products_id.*',
361
+ 'images.*'
362
+ ],
363
+ limit: 10,
364
+ filter: {
365
+ products: {
366
+ products_id: {
367
+ type: {
368
+ _eq: "event"
369
+ }
370
+ }
371
+ },
372
+ }
373
+ }))
374
+ })
375
+
376
+ const {
377
+ data: callouts
378
+ } = await useAsyncData('callouts', () => {
379
+ return $directus.request($readItem('callouts', '2'))
380
+ })
381
+
382
+ useHead({
383
+ title: computed(() => department?.value?.name || 'Department Page')
384
+ });
385
+ </script>
@@ -0,0 +1,135 @@
1
+ <template>
2
+ <div v-if="category">
3
+
4
+ <!-- Special Categories -->
5
+ <div v-if="category.slug === 'charts'">
6
+ <charts />
7
+ </div>
8
+
9
+ <div v-else-if="category.slug === 'radio-stations'">
10
+ <stations />
11
+ </div>
12
+
13
+ <div v-else-if="category.slug === 'eats'">
14
+ <eats />
15
+ </div>
16
+
17
+ <div v-else-if="category.slug === 'restaurants'">
18
+ <div v-for="(shop, i) in restaurantsList" :key="i">
19
+ <restaurants :restaurant="shop" />
20
+ </div>
21
+ </div>
22
+
23
+ <!-- Default Category Layout -->
24
+ <v-card variant="text" v-else>
25
+ <v-toolbar :style="`background-color: ${category?.color}; color: ${category?.colortext}`">
26
+ <v-toolbar-title><NuxtLink :to="`/departments/${category?.departments?.[0]?.departments_id?.name}`">Meeovi {{ category?.departments?.[0]?.departments_id?.name }}</NuxtLink> - {{ category?.name }}</v-toolbar-title>
27
+ <v-slide-group show-arrows v-if="category?.categories?.length">
28
+ <v-slide-group-item v-slot="{ isSelected, toggle }">
29
+ <v-menu>
30
+ <template #activator="{ props }">
31
+ <v-btn :color="isSelected ? 'primary' : undefined" class="ma-2" v-bind="props"
32
+ variant="text">
33
+ Categories
34
+ </v-btn>
35
+ </template>
36
+
37
+ <v-list class="departmentMenu">
38
+ <v-row>
39
+ <v-col cols="3" v-for="sub in category.categories" :key="sub?.categories_id?.id">
40
+ <v-list-item>
41
+ <NuxtLink :to="`/departments/categories/${sub.categories_id.id}`">
42
+ {{ sub.categories_id.name }}
43
+ </NuxtLink>
44
+ </v-list-item>
45
+ </v-col>
46
+ </v-row>
47
+ </v-list>
48
+ </v-menu>
49
+ </v-slide-group-item>
50
+
51
+ <v-slide-group-item v-for="menu in category.menus" :key="menu.id" v-slot="{ isSelected, toggle }">
52
+ <v-btn :color="isSelected ? 'primary' : undefined" class="ma-2" :href="menu.url">
53
+ {{ menu.name }}
54
+ </v-btn>
55
+ </v-slide-group-item>
56
+ </v-slide-group>
57
+ </v-toolbar>
58
+ </v-card>
59
+
60
+ <!-- Product List -->
61
+ <v-row>
62
+ <v-col cols="3" v-for="productRel in category.products" :key="productRel.products_id.id">
63
+ <productCard :product="productRel.products_id" />
64
+ </v-col>
65
+ </v-row>
66
+
67
+ </div>
68
+
69
+ <!-- Loading / Not Found -->
70
+ <div v-else class="p-10 text-center text-xl text-neutral-700">
71
+ Loading category...
72
+ </div>
73
+ </template>
74
+
75
+ <script setup>
76
+ import charts from '~/components/categories/charts.vue'
77
+ import stations from '~/components/categories/stations.vue'
78
+ import eats from '~/components/categories/eats.vue'
79
+ import restaurants from '~/components/categories/restaurants.vue'
80
+ import productCard from '#commerce/app/components/catalog/product/productCard.vue'
81
+
82
+ const route = useRoute()
83
+ const {
84
+ $directus,
85
+ $readItem,
86
+ $readItems
87
+ } = useNuxtApp()
88
+
89
+ const slug = computed(() => {
90
+ const s = route.params.slug
91
+ return Array.isArray(s) ? s[0] : s
92
+ })
93
+
94
+ const {
95
+ data: categoryRaw
96
+ } = await useAsyncData('categoryRaw', () => {
97
+ return $directus.request(
98
+ $readItems('categories', {
99
+ fields: [
100
+ '*',
101
+ 'tags.tags_id.*',
102
+ 'departments.departments_id.*',
103
+ 'products.products_id.*',
104
+ 'products.products_id.image.*',
105
+ 'menus.*',
106
+ 'image.*'
107
+ ],
108
+ filter: {
109
+ slug: {
110
+ _eq: slug.value
111
+ }
112
+ },
113
+ limit: 1
114
+ })
115
+ )
116
+ })
117
+
118
+ // Unwrap array cleanly
119
+ const category = computed(() => categoryRaw.value?.[0] || null)
120
+
121
+
122
+ // FETCH SHOPS FOR RESTAURANTS CATEGORY
123
+ const {
124
+ data: restaurantsList
125
+ } = await useAsyncData('restaurantsList', () => {
126
+ return $directus.request($readItems('shops', {
127
+ fields: ['*']
128
+ }))
129
+ })
130
+
131
+ // SEO
132
+ useHead({
133
+ title: computed(() => category.value?.name || 'Category Page')
134
+ })
135
+ </script>
@@ -246,14 +246,14 @@
246
246
  computed,
247
247
  watch
248
248
  } from 'vue';
249
- import comments from '#social/app/components/blocks/comments.vue'
249
+ import comments from '@/components/placeholders/Comments.vue'
250
250
 
251
251
  import productDetails from '../../components/catalog/product/productDetails.vue'
252
252
  import productSpecs from '../../components/catalog/product/productSpecs.vue'
253
253
  import productCard from '../../components/catalog/product/productCard.vue'
254
254
  import giftCard from '../../components/catalog/product/giftCard.vue'
255
- import short from '#social/app/components/related/short.vue'
256
- import spaces from '#social/app/components/related/space.vue'
255
+ import short from '@/components/placeholders/Short.vue'
256
+ import spaces from '@/components/placeholders/Space.vue'
257
257
  import shop from '../../components/catalog/shops/stores.vue'
258
258
 
259
259
  const tab = ref(null);
@@ -100,31 +100,27 @@
100
100
  </template>
101
101
 
102
102
  <script setup>
103
- import {
104
- ref
105
- } from 'vue'
103
+ import { ref } from 'vue'
106
104
  import showcases from '~/components/catalog/product/relatedproducts.vue'
107
105
  import productCard from '~/components/catalog/product/productCard.vue'
108
- import comments from '#social/app/components/comments.vue'
109
- import spaces from '#social/app/components/space.vue'
110
- import events from '#social/app/components/event.vue'
106
+ import comments from '@/components/placeholders/Comments.vue'
107
+ import spaces from '@/components/placeholders/Space.vue'
108
+ import events from '@/components/placeholders/Event.vue'
109
+ import { useContentFallback } from '../../composables/useContent'
111
110
 
112
111
  const route = useRoute();
113
112
  const tab = ref(null);
114
- const {
115
- $directus,
116
- $readItem
117
- } = useNuxtApp()
113
+ const { $directus, $readItem } = useNuxtApp()
118
114
 
119
115
  const slug = computed(() => {
120
116
  const s = route.params.slug
121
117
  return Array.isArray(s) ? s[0] : s
122
118
  })
123
119
 
124
- const {
125
- data: shopRaw
126
- } = await useAsyncData('shop', () => {
127
- return $directus.request($readItem('shops', {
120
+ const content = useContentFallback()
121
+
122
+ const { data: shopRaw } = await useAsyncData('shop', () => {
123
+ return content.listShops({
128
124
  fields: ['*',
129
125
  'media.*',
130
126
  'spaces.spaces_id.*',
@@ -143,14 +139,12 @@
143
139
  }
144
140
  },
145
141
  limit: 1
146
- }))
142
+ })
147
143
  })
148
144
 
149
145
  const shop = computed(() => shopRaw.value?.[0] || null)
150
146
 
151
- const {
152
- data: shopbar
153
- } = await useAsyncData('shopbar', () => {
147
+ const { data: shopbar } = await useAsyncData('shopbar', () => {
154
148
  return $directus.request($readItem('navigation', '55'))
155
149
  })
156
150