@meeovi/layer-commerce 1.0.3 → 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 +2 -1
  58. package/tsconfig.json +10 -1
@@ -74,11 +74,9 @@
74
74
  return null
75
75
  })
76
76
 
77
- const {
78
- $directus,
79
- $readItem,
80
- $readItems
81
- } = useNuxtApp()
77
+ const { $commerce } = useNuxtApp()
78
+ import { useCatalogFallback } from '../../../composables/useCatalog'
79
+ const catalog = useCatalogFallback()
82
80
  const tab = ref(null);
83
81
 
84
82
  const {
@@ -105,22 +103,11 @@
105
103
  const {
106
104
  data: subscriptions
107
105
  } = await useAsyncData('subscriptions', async () => {
108
- const resp = await $directus.request($readItems('products', {
109
- fields: ['*', {
110
- '*': ['*']
111
- }],
112
- filter: {
113
- user_id: {
114
- _eq: user?.id
115
- },
116
- type: {
117
- name: {
118
- _eq: 'Subscription'
119
- }
120
- }
121
- }
122
- }))
123
- return resp?.data ?? resp ?? []
106
+ const resp = await catalog.listProducts({
107
+ fields: ['*', { '*': ['*'] }],
108
+ filter: { user_id: { _eq: user?.id }, type: { name: { _eq: 'Subscription' } } }
109
+ })
110
+ return resp || []
124
111
  })
125
112
 
126
113
 
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <div class="comments-placeholder">
3
+ <p v-if="productName"><strong>Comments for:</strong> {{ productName }}</p>
4
+ <slot />
5
+ </div>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ const props = defineProps({
10
+ productName: { type: String, required: false },
11
+ productImage: { type: String, required: false },
12
+ productSku: { type: [String, Number], required: false },
13
+ comments: { type: Array, required: false }
14
+ })
15
+ </script>
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <button class="create-list-btn" @click="$emit('create', lists)">Create List</button>
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ const props = defineProps({ lists: { type: [String, Number, Object], required: false } })
7
+ </script>
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <div class="event-placeholder">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ const props = defineProps({ space: { type: Object, required: false } })
9
+ </script>
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <div class="list-showcases-placeholder">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ const props = defineProps({ list: { type: Object, required: false } })
9
+ </script>
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <div class="short-placeholder">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ const props = defineProps({ short: { type: Object, required: false } })
9
+ </script>
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <div class="space-placeholder">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ const props = defineProps({ space: { type: Object, required: false } })
9
+ </script>
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <span class="tag-placeholder">{{ tag?.name || tag }}</span>
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ const props = defineProps({ tag: { type: Object, required: false } })
7
+ </script>
@@ -1,15 +1,16 @@
1
- import type { SfAddress, Maybe } from '@vue-storefront/unified-data-model';
1
+ import type { Maybe } from '../../composables/_types'
2
2
 
3
- export interface Address extends SfAddress {
4
- streetNumber: Maybe<string>;
5
- phone: Maybe<string>;
6
- streetName: Maybe<string>;
3
+ export interface Address {
4
+ streetNumber?: Maybe<string>
5
+ phone?: Maybe<string>
6
+ streetName?: Maybe<string>
7
+ [key: string]: any
7
8
  }
8
9
 
9
10
  export type CheckoutAddressProps = {
10
- type: 'billingAddress' | 'shippingAddress';
11
- heading: string;
12
- description: string;
13
- buttonText: string;
14
- savedAddress?: Maybe<SfAddress>;
15
- };
11
+ type: 'billingAddress' | 'shippingAddress'
12
+ heading: string
13
+ description: string
14
+ buttonText: string
15
+ savedAddress?: Maybe<Address>
16
+ }
@@ -1,5 +1,5 @@
1
- import type { SfCart } from '@vue-storefront/unified-data-model';
1
+ import type { Cart } from '../../composables/_types'
2
2
 
3
3
  export type OrderSummaryPropsType = {
4
- cart: SfCart;
5
- };
4
+ cart: Cart
5
+ }
@@ -108,11 +108,9 @@
108
108
 
109
109
  const user = useSupabaseUser()
110
110
 
111
- const {
112
- $directus,
113
- $readItem,
114
- $readItems
115
- } = useNuxtApp()
111
+ const { $commerce } = useNuxtApp()
112
+ import { useCatalogFallback } from '../../../composables/useCatalog'
113
+ const catalog = useCatalogFallback()
116
114
  const tab = ref(null);
117
115
 
118
116
  const {
@@ -202,43 +200,21 @@
202
200
  const {
203
201
  data: giftCards
204
202
  } = await useAsyncData('giftCards', async () => {
205
- const resp = await $directus.request($readItems('products', {
206
- fields: ['*', {
207
- '*': ['*']
208
- }],
209
- filter: {
210
- user_id: {
211
- _eq: user?.id
212
- },
213
- incentive_type: {
214
- name: {
215
- _eq: 'Gift Card'
216
- }
217
- }
218
- }
219
- }))
220
- return resp?.data ?? resp ?? []
203
+ const resp = await catalog.listProducts({
204
+ fields: ['*', { '*': ['*'] }],
205
+ filter: { user_id: { _eq: user?.id }, incentive_type: { name: { _eq: 'Gift Card' } } }
206
+ })
207
+ return resp || []
221
208
  })
222
209
 
223
210
  const {
224
211
  data: certificates
225
212
  } = await useAsyncData('certificates', async () => {
226
- const resp = await $directus.request($readItems('products', {
227
- fields: ['*', {
228
- '*': ['*']
229
- }],
230
- filter: {
231
- user_id: {
232
- _eq: user?.id
233
- },
234
- incentive_type: {
235
- name: {
236
- _eq: 'Gift Certificate'
237
- }
238
- }
239
- }
240
- }))
241
- return resp?.data ?? resp ?? []
213
+ const resp = await catalog.listProducts({
214
+ fields: ['*', { '*': ['*'] }],
215
+ filter: { user_id: { _eq: user?.id }, incentive_type: { name: { _eq: 'Gift Certificate' } } }
216
+ })
217
+ return resp || []
242
218
  })
243
219
 
244
220
  useHead({
@@ -11,3 +11,10 @@ export function getCartProvider(name: string) {
11
11
  if (!provider) throw new Error(`Cart provider "${name}" not found`)
12
12
  return provider
13
13
  }
14
+
15
+ // Runtime helper for adapter packages to register themselves when the
16
+ // app boots. Adapter packages can import this and call it from their
17
+ // plugin entry to wire into the commerce cart provider registry.
18
+ export function registerCartProviderRuntime(name: string, provider: CartProvider) {
19
+ registerCartProvider(name, provider)
20
+ }
@@ -3,3 +3,4 @@ export * from "./helpers";
3
3
  export * from "./methods";
4
4
  export * from "./models";
5
5
  export * from "./validationRules";
6
+ export * from "./registry";
@@ -11,3 +11,10 @@ export function getProductProvider(name: string) {
11
11
  if (!provider) throw new Error(`Product provider "${name}" not found`)
12
12
  return provider
13
13
  }
14
+
15
+ // Runtime helper for adapter packages to register themselves when the
16
+ // app boots. Adapter packages can import this and call it from their
17
+ // plugin entry to wire into the commerce product provider registry.
18
+ export function registerProductProviderRuntime(name: string, provider: ProductProvider) {
19
+ registerProductProvider(name, provider)
20
+ }
@@ -0,0 +1,21 @@
1
+ import type { ProductProvider } from './products/types'
2
+ import type { CartProvider } from './cart/types'
3
+ import { registerProductProvider } from './products/registry'
4
+ import { registerCartProvider } from './cart/registry'
5
+
6
+ export interface CommerceProviderBundle {
7
+ product?: ProductProvider
8
+ cart?: CartProvider
9
+ // future: category?: CategoryProvider
10
+ }
11
+
12
+ // Register multiple domain providers at once from an adapter package.
13
+ // Example adapter entrypoint can call this during app boot.
14
+ export function registerCommerceProviderRuntime(name: string, bundle: CommerceProviderBundle) {
15
+ if (bundle.product) registerProductProvider(name, bundle.product)
16
+ if (bundle.cart) registerCartProvider(name, bundle.cart)
17
+ }
18
+
19
+ // Also re-export individual runtime helpers for convenience
20
+ export { registerProductProviderRuntime } from './products/registry'
21
+ export { registerCartProviderRuntime } from './cart/registry'
@@ -0,0 +1,64 @@
1
+ import { ref, watchEffect } from 'vue'
2
+ import { useAlternateContext } from '@meeovi/core'
3
+
4
+ export function useCatalogFallback() {
5
+ // Attempt to use core runtime adapter if present
6
+ try {
7
+ const ctx = useAlternateContext() as any
8
+ const adapter = ctx.getAdapter('catalog')
9
+ if (adapter) {
10
+ return {
11
+ adapter,
12
+ async getProductById(id: string) {
13
+ return adapter.getProductById(id)
14
+ },
15
+ async getProductBySlug(slug: string) {
16
+ return adapter.getProductBySlug(slug)
17
+ },
18
+ async listProducts(params?: Record<string, unknown>) {
19
+ return adapter.listProducts(params)
20
+ }
21
+ }
22
+ }
23
+ } catch (e) {
24
+ // runtime context not available
25
+ }
26
+
27
+ // Fallback to Directus via Nuxt app runtime (assumes component calling runs in Vue context)
28
+ return {
29
+ adapter: null,
30
+ async getProductById(_id: string) {
31
+ const nuxtApp = useNuxtApp() as any
32
+ if (nuxtApp?.$directus && nuxtApp.$readItem) {
33
+ const res = await nuxtApp.$directus.request(nuxtApp.$readItem('products', { filter: { id: { _eq: _id } }, limit: 1 }))
34
+ return res?.[0] || null
35
+ }
36
+ return null
37
+ },
38
+ async getProductBySlug(slug: string) {
39
+ const nuxtApp = useNuxtApp() as any
40
+ if (nuxtApp?.$directus && nuxtApp.$readItem) {
41
+ const res = await nuxtApp.$directus.request(nuxtApp.$readItem('products', { filter: { slug: { _eq: slug } }, limit: 1 }))
42
+ return res?.[0] || null
43
+ }
44
+ return null
45
+ },
46
+ async listProducts(params?: Record<string, unknown>) {
47
+ const nuxtApp = useNuxtApp() as any
48
+ if (nuxtApp?.$directus && nuxtApp.$readItems) {
49
+ const res = await nuxtApp.$directus.request(nuxtApp.$readItems('products', params || {}))
50
+ return res || []
51
+ }
52
+ return []
53
+ }
54
+ ,
55
+ async listAttributes(filter?: Record<string, unknown>) {
56
+ const nuxtApp = useNuxtApp() as any
57
+ if (nuxtApp?.$directus && nuxtApp.$readItems) {
58
+ const res = await nuxtApp.$directus.request(nuxtApp.$readItems('attributes', filter || {}))
59
+ return res || []
60
+ }
61
+ return []
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,57 @@
1
+ import { useAlternateContext } from '@meeovi/core'
2
+
3
+ export function useContentFallback() {
4
+ try {
5
+ const ctx = useAlternateContext() as any
6
+ const adapter = ctx.getAdapter('catalog')
7
+ // If a content-capable adapter is available and exposes methods, use it
8
+ if (adapter && typeof adapter.listShops === 'function') {
9
+ return {
10
+ adapter,
11
+ listShops: (opts?: any) => adapter.listShops(opts),
12
+ getBrandBySlug: (slug: string) => adapter.getBrandBySlug?.(slug),
13
+ getPage: (id: string) => adapter.getPage?.(id)
14
+ }
15
+ }
16
+ } catch (e) {
17
+ // ignore
18
+ }
19
+
20
+ // Fallback to Directus via Nuxt runtime
21
+ return {
22
+ adapter: null,
23
+ async listShops(params?: Record<string, unknown>) {
24
+ const nuxtApp = useNuxtApp() as any
25
+ if (nuxtApp?.$directus && nuxtApp.$readItems) {
26
+ const res = await nuxtApp.$directus.request(nuxtApp.$readItems('shops', params || {}))
27
+ return res || []
28
+ }
29
+ return []
30
+ },
31
+ async listBrands(params?: Record<string, unknown>) {
32
+ const nuxtApp = useNuxtApp() as any
33
+ if (nuxtApp?.$directus && nuxtApp.$readItems) {
34
+ const res = await nuxtApp.$directus.request(nuxtApp.$readItems('brands', params || {}))
35
+ return res || []
36
+ }
37
+ return []
38
+ },
39
+ async getBrandBySlug(slug: string) {
40
+ const nuxtApp = useNuxtApp() as any
41
+ if (nuxtApp?.$directus && nuxtApp.$readItems) {
42
+ const res = await nuxtApp.$directus.request(nuxtApp.$readItems('brands', { filter: { slug: { _eq: slug } }, limit: 1 }))
43
+ return res?.[0] || null
44
+ }
45
+ return null
46
+ },
47
+ async getPage(id: string) {
48
+ const nuxtApp = useNuxtApp() as any
49
+ if (nuxtApp?.$directus && nuxtApp.$readItem) {
50
+ return await nuxtApp.$directus.request(nuxtApp.$readItem('pages', id))
51
+ }
52
+ return null
53
+ }
54
+ }
55
+ }
56
+
57
+ export default useContentFallback
@@ -1,17 +1,22 @@
1
- import { Ref } from 'vue';
2
- import type { GetProducts } from '@vue-storefront/storefront-boilerplate-sdk';
3
- import type { Maybe } from '../_types';
1
+ import { Ref } from 'vue'
2
+ import type { Product } from '../_types'
3
+ import type { Maybe } from '../_types'
4
+
5
+ export type GetProducts = {
6
+ items: Product[]
7
+ total?: number
8
+ }
4
9
 
5
10
  export interface UseProductsState {
6
- data: GetProducts | null;
7
- loading: boolean;
11
+ data: GetProducts | null
12
+ loading: boolean
8
13
  }
9
14
 
10
- export type FetchProducts = () => Promise<Ref<Maybe<GetProducts>>>;
15
+ export type FetchProducts = () => Promise<Ref<Maybe<GetProducts>>>
11
16
  export interface UseProducts {
12
- data: Readonly<Ref<UseProductsState['data']>>;
13
- loading: Readonly<Ref<boolean>>;
14
- fetchProducts: FetchProducts;
17
+ data: Readonly<Ref<UseProductsState['data']>>
18
+ loading: Readonly<Ref<boolean>>
19
+ fetchProducts: FetchProducts
15
20
  }
16
21
 
17
- export type UseProductsReturn = () => UseProducts;
22
+ export type UseProductsReturn = () => UseProducts
@@ -43,7 +43,7 @@
43
43
  </template>
44
44
 
45
45
  <script setup>
46
- import shorts from '#social/app/components/features/vibeSections/shorts.vue'
46
+ import shorts from '@/components/placeholder/shorts.vue'
47
47
  import productCard from '@/components/catalog/product/productCard.vue'
48
48
  import relatedbrands from '@/components/catalog/product/relatedbrands.vue'
49
49
  import {