@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.
- package/app/components/catalog/product/ProductAccordion/types.ts +3 -3
- package/app/components/catalog/product/ProductProperties/types.ts +3 -3
- package/app/components/catalog/product/ProductSlider/types.ts +5 -5
- package/app/components/catalog/product/RecommendedProducts/types.ts +3 -3
- package/app/components/catalog/product/bestsellers.vue +8 -20
- package/app/components/catalog/product/deals.vue +7 -22
- package/app/components/catalog/product/exclusives.vue +8 -10
- package/app/components/catalog/product/featuredproducts.vue +8 -20
- package/app/components/catalog/product/latestproducts.vue +8 -20
- package/app/components/catalog/product/productCard.vue +55 -21
- package/app/components/catalog/product/productDetails.vue +20 -14
- package/app/components/catalog/product/relatedproducts.vue +5 -20
- package/app/components/catalog/product/sizeOptions.vue +3 -8
- package/app/components/catalog/shops/relatedstores.vue +6 -21
- package/app/components/categories/chart/[id].vue +200 -0
- package/app/components/categories/chart/add-chart.vue +142 -0
- package/app/components/categories/chart/chart.vue +82 -0
- package/app/components/categories/chart/monthlyChart.vue +46 -0
- package/app/components/categories/chart/weeklyChart.vue +46 -0
- package/app/components/categories/chart/yearlyChart.vue +46 -0
- package/app/components/categories/charts.vue +118 -0
- package/app/components/categories/deals.vue +101 -0
- package/app/components/categories/eats.vue +49 -0
- package/app/components/categories/restaurants.vue +26 -0
- package/app/components/categories/station/[id].vue +72 -0
- package/app/components/categories/stations.vue +124 -0
- package/app/components/categories/time/time.vue +63 -0
- package/app/components/categories/travel.vue +75 -0
- package/app/components/categories/weather/weather.vue +44 -0
- package/app/components/content/pages/showcases.vue +1 -1
- package/app/components/marketing/promotions/giftcards.vue +20 -45
- package/app/components/marketing/promotions/subscriptions.vue +8 -21
- package/app/components/placeholders/Comments.vue +15 -0
- package/app/components/placeholders/CreateListBtn.vue +7 -0
- package/app/components/placeholders/Event.vue +9 -0
- package/app/components/placeholders/ListShowcases.vue +9 -0
- package/app/components/placeholders/Short.vue +9 -0
- package/app/components/placeholders/Space.vue +9 -0
- package/app/components/placeholders/Tag.vue +7 -0
- package/app/components/sales/CheckoutAddress/types.ts +12 -11
- package/app/components/sales/OrderSummary/types.ts +3 -3
- package/app/components/sales/incentives.vue +13 -37
- package/app/composables/cart/registry.ts +7 -0
- package/app/composables/index.ts +1 -0
- package/app/composables/products/registry.ts +7 -0
- package/app/composables/registry.ts +21 -0
- package/app/composables/useCatalog.ts +64 -0
- package/app/composables/useContent.ts +57 -0
- package/app/composables/useProducts/types.ts +15 -10
- package/app/pages/brand/[...slug].vue +1 -1
- package/app/pages/departments/[...slug].vue +385 -0
- package/app/pages/departments/category/[...slug].vue +135 -0
- package/app/pages/product/[...id].vue +3 -3
- package/app/pages/shop/[...slug].vue +12 -18
- package/app/pages/shops.vue +18 -25
- package/global.d.ts +14 -0
- package/package.json +2 -1
- package/tsconfig.json +10 -1
|
@@ -74,11 +74,9 @@
|
|
|
74
74
|
return null
|
|
75
75
|
})
|
|
76
76
|
|
|
77
|
-
const {
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
109
|
-
fields: ['*', {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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>
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Maybe } from '../../composables/_types'
|
|
2
2
|
|
|
3
|
-
export interface Address
|
|
4
|
-
streetNumber
|
|
5
|
-
phone
|
|
6
|
-
streetName
|
|
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<
|
|
15
|
-
}
|
|
11
|
+
type: 'billingAddress' | 'shippingAddress'
|
|
12
|
+
heading: string
|
|
13
|
+
description: string
|
|
14
|
+
buttonText: string
|
|
15
|
+
savedAddress?: Maybe<Address>
|
|
16
|
+
}
|
|
@@ -108,11 +108,9 @@
|
|
|
108
108
|
|
|
109
109
|
const user = useSupabaseUser()
|
|
110
110
|
|
|
111
|
-
const {
|
|
112
|
-
|
|
113
|
-
|
|
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
|
|
206
|
-
fields: ['*', {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
|
227
|
-
fields: ['*', {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
+
}
|
package/app/composables/index.ts
CHANGED
|
@@ -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 {
|
|
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 '
|
|
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 {
|