@mframework/layer-commerce 0.0.3
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/README.md +101 -0
- package/app/cart/useCart.ts +1 -0
- package/app/components/ChevronIcon/ChevronIcon.config.ts +17 -0
- package/app/components/DateSelect/DateSelect.config.ts +15 -0
- package/app/components/Field/Field.config.ts +14 -0
- package/app/components/FieldDate/FieldDate.config.ts +16 -0
- package/app/components/Form/Form.type.ts +8 -0
- package/app/components/Product/Product.config.ts +19 -0
- package/app/components/Product/Stock.config.ts +15 -0
- package/app/components/ProductCustomizableOption/ProductCustomizableOption.config.ts +5 -0
- package/app/components/ProductGallery/ProductGallery.config.ts +15 -0
- package/app/components/ProductReviews/ProductReviews.config.ts +8 -0
- package/app/composables/_types.ts +18 -0
- package/app/composables/adapters/abstract/cartAdapter.ts +0 -0
- package/app/composables/adapters/abstract/categoryAdapter.ts +0 -0
- package/app/composables/adapters/abstract/customerAdapter.ts +0 -0
- package/app/composables/adapters/abstract/inventoryAdapter.ts +0 -0
- package/app/composables/adapters/abstract/orderAdapter.ts +0 -0
- package/app/composables/adapters/abstract/productAdapter.ts +7 -0
- package/app/composables/cart/registry.ts +20 -0
- package/app/composables/cart/types.ts +18 -0
- package/app/composables/cart/useCart.ts +15 -0
- package/app/composables/config.ts +19 -0
- package/app/composables/defs/apiDefinitions.ts +55 -0
- package/app/composables/defs/extension.feature +40 -0
- package/app/composables/defs/extension.mocks.ts +39 -0
- package/app/composables/defs/extension.test.ts +280 -0
- package/app/composables/defs/extension.ts +236 -0
- package/app/composables/defs/index.ts +3 -0
- package/app/composables/defs/typeHelpers.ts +8 -0
- package/app/composables/defs/types.ts +136 -0
- package/app/composables/domain/product.ts +12 -0
- package/app/composables/featured-products.ts +20 -0
- package/app/composables/helpers/contextualizedNormalizers.feature +14 -0
- package/app/composables/helpers/contextualizedNormalizers.test.ts +85 -0
- package/app/composables/helpers/contextualizedNormalizers.ts +20 -0
- package/app/composables/helpers/index.ts +1 -0
- package/app/composables/index.ts +9 -0
- package/app/composables/methods/auth.ts +83 -0
- package/app/composables/methods/cart.ts +119 -0
- package/app/composables/methods/category.ts +27 -0
- package/app/composables/methods/checkout.ts +54 -0
- package/app/composables/methods/customer.ts +52 -0
- package/app/composables/methods/helpers.ts +5 -0
- package/app/composables/methods/index.ts +75 -0
- package/app/composables/methods/order.ts +39 -0
- package/app/composables/methods/product.ts +95 -0
- package/app/composables/methods/settings.ts +16 -0
- package/app/composables/models/cart.ts +95 -0
- package/app/composables/models/category.ts +13 -0
- package/app/composables/models/checkout.ts +17 -0
- package/app/composables/models/customer.ts +16 -0
- package/app/composables/models/facets.ts +25 -0
- package/app/composables/models/index.ts +94 -0
- package/app/composables/models/order.ts +43 -0
- package/app/composables/models/product.ts +73 -0
- package/app/composables/models/shared.ts +75 -0
- package/app/composables/orders.ts +69 -0
- package/app/composables/products/registry.ts +86 -0
- package/app/composables/products/types.ts +8 -0
- package/app/composables/products/useEvents.ts +26 -0
- package/app/composables/products/useGiftCards.ts +29 -0
- package/app/composables/products/useProducts.ts +12 -0
- package/app/composables/products/useSubscriptions.ts +29 -0
- package/app/composables/products.ts +30 -0
- package/app/composables/registry.ts +24 -0
- package/app/composables/useAuth.ts +43 -0
- package/app/composables/useBreakpoints/index.ts +1 -0
- package/app/composables/useBreakpoints/useBreakpoints.ts +28 -0
- package/app/composables/useCache.ts +38 -0
- package/app/composables/useCart/__tests__/useCart.spec.ts +11 -0
- package/app/composables/useCart/index.ts +1 -0
- package/app/composables/useCart/types.ts +17 -0
- package/app/composables/useCart/useCart.ts +46 -0
- package/app/composables/useCartShippingMethods/__tests__/useCartShippingMethods.spec.ts +11 -0
- package/app/composables/useCartShippingMethods/index.ts +1 -0
- package/app/composables/useCartShippingMethods/types.ts +17 -0
- package/app/composables/useCartShippingMethods/useCartShippingMethods.ts +47 -0
- package/app/composables/useCatalog.ts +26 -0
- package/app/composables/useContent.ts +26 -0
- package/app/composables/useCustomer/__tests__/useCustomer.spec.ts +25 -0
- package/app/composables/useCustomer/index.ts +2 -0
- package/app/composables/useCustomer/types.ts +17 -0
- package/app/composables/useCustomer/useCustomer.ts +40 -0
- package/app/composables/useCustomerAddress/__tests__/useCustomerAddress.spec.ts +11 -0
- package/app/composables/useCustomerAddress/index.ts +2 -0
- package/app/composables/useCustomerAddress/types.ts +17 -0
- package/app/composables/useCustomerAddress/useCustomerAddress.ts +55 -0
- package/app/composables/useCustomerOrder/__tests__/useCustomerOrder.spec.ts +11 -0
- package/app/composables/useCustomerOrder/adress.ts +10 -0
- package/app/composables/useCustomerOrder/index.ts +2 -0
- package/app/composables/useCustomerOrder/product.ts +37 -0
- package/app/composables/useCustomerOrder/types.ts +40 -0
- package/app/composables/useCustomerOrder/useCustomerOrder.ts +63 -0
- package/app/composables/useCustomerOrders/__tests__/useCustomerOrders.spec.ts +11 -0
- package/app/composables/useCustomerOrders/index.ts +2 -0
- package/app/composables/useCustomerOrders/types.ts +20 -0
- package/app/composables/useCustomerOrders/useCustomerOrders.ts +56 -0
- package/app/composables/useCustomerReturns/__tests__/useCustomerReturns.spec.ts +11 -0
- package/app/composables/useCustomerReturns/index.ts +2 -0
- package/app/composables/useCustomerReturns/types.ts +17 -0
- package/app/composables/useCustomerReturns/useCustomerReturns.ts +41 -0
- package/app/composables/useHandleError/index.ts +1 -0
- package/app/composables/useHandleError/types.ts +11 -0
- package/app/composables/useHandleError/useHandleError.ts +27 -0
- package/app/composables/useInventory.ts +29 -0
- package/app/composables/useLoading.ts +21 -0
- package/app/composables/useNotification.ts +21 -0
- package/app/composables/usePageTitle.ts +20 -0
- package/app/composables/useProduct/index.ts +2 -0
- package/app/composables/useProduct/types.ts +17 -0
- package/app/composables/useProduct/useProduct.ts +42 -0
- package/app/composables/useProductAttribute/__tests__/useProduct.mock.ts +31 -0
- package/app/composables/useProductAttribute/__tests__/useProductAttribute.spec.ts +14 -0
- package/app/composables/useProductAttribute/index.ts +1 -0
- package/app/composables/useProductAttribute/useProductAttribute.ts +37 -0
- package/app/composables/useProductRecommended/__tests__/useProductRecommended.spec.ts +12 -0
- package/app/composables/useProductRecommended/index.ts +1 -0
- package/app/composables/useProductRecommended/types.ts +17 -0
- package/app/composables/useProductRecommended/useProductRecommended.ts +43 -0
- package/app/composables/useProductReviews/__tests__/productReviews.mock.ts +20 -0
- package/app/composables/useProductReviews/__tests__/useProductReviews.spec.ts +22 -0
- package/app/composables/useProductReviews/index.ts +2 -0
- package/app/composables/useProductReviews/types.ts +17 -0
- package/app/composables/useProductReviews/useProductReviews.ts +46 -0
- package/app/composables/useProducts/__tests__/useProducts.spec.ts +11 -0
- package/app/composables/useProducts/types.ts +22 -0
- package/app/composables/useProducts/useProducts.ts +41 -0
- package/app/composables/useTax.ts +27 -0
- package/app/composables/validationRules/index.ts +1 -0
- package/app/composables/validationRules/password.feature +67 -0
- package/app/composables/validationRules/password.test.ts +89 -0
- package/app/composables/validationRules/password.ts +25 -0
- package/app/normalizers/Cart.query.ts +729 -0
- package/app/normalizers/Cart.type.ts +285 -0
- package/app/normalizers/Category.query.ts +146 -0
- package/app/normalizers/Category.type.ts +55 -0
- package/app/normalizers/CheckEmail.query.ts +28 -0
- package/app/normalizers/Checkout.query.ts +253 -0
- package/app/normalizers/Checkout.type.ts +77 -0
- package/app/normalizers/CmsBlock.query.ts +57 -0
- package/app/normalizers/CmsBlock.type.ts +25 -0
- package/app/normalizers/CmsPage.query.ts +59 -0
- package/app/normalizers/CmsPage.type.ts +26 -0
- package/app/normalizers/Config.query.ts +224 -0
- package/app/normalizers/Config.type.ts +196 -0
- package/app/normalizers/ContactForm.query.ts +49 -0
- package/app/normalizers/CreditMemo.type.ts +49 -0
- package/app/normalizers/GiftCard.type.ts +24 -0
- package/app/normalizers/Invoice.type.ts +58 -0
- package/app/normalizers/Menu.query.ts +54 -0
- package/app/normalizers/Menu.type.ts +22 -0
- package/app/normalizers/MyAccount.query.ts +268 -0
- package/app/normalizers/MyAccount.type.ts +129 -0
- package/app/normalizers/NewsletterSubscription.query.ts +38 -0
- package/app/normalizers/Order.query.ts +741 -0
- package/app/normalizers/Order.type.ts +268 -0
- package/app/normalizers/Payment.type.ts +28 -0
- package/app/normalizers/ProductAlerts.query.ts +23 -0
- package/app/normalizers/ProductCompare.query.ts +226 -0
- package/app/normalizers/ProductCompare.type.ts +90 -0
- package/app/normalizers/ProductList.query.ts +1620 -0
- package/app/normalizers/ProductList.type.ts +726 -0
- package/app/normalizers/Region.query.ts +58 -0
- package/app/normalizers/Region.type.ts +23 -0
- package/app/normalizers/Return.type.ts +50 -0
- package/app/normalizers/Review.query.ts +81 -0
- package/app/normalizers/Review.type.ts +42 -0
- package/app/normalizers/Slider.query.ts +72 -0
- package/app/normalizers/Slider.type.ts +26 -0
- package/app/normalizers/StoreInPickUp.query.ts +54 -0
- package/app/normalizers/StoreInPickUp.type.ts +59 -0
- package/app/normalizers/Subscription.type.ts +25 -0
- package/app/normalizers/Transaction.type.ts +20 -0
- package/app/normalizers/UrlRewrites.query.ts +55 -0
- package/app/normalizers/UrlRewrites.type.ts +25 -0
- package/app/normalizers/Wishlist.query.ts +202 -0
- package/app/normalizers/Wishlist.type.ts +42 -0
- package/app/pages/brand/[...slug].vue +76 -0
- package/app/pages/brands.vue +67 -0
- package/app/pages/cart.vue +142 -0
- package/app/pages/compare.vue +166 -0
- package/app/pages/departments/[...slug].vue +353 -0
- package/app/pages/departments/category/[...slug].vue +114 -0
- package/app/pages/incentive/[...id].vue +66 -0
- package/app/pages/invoice/[id].vue +309 -0
- package/app/pages/order/[id].vue +327 -0
- package/app/pages/product/[...id].vue +309 -0
- package/app/pages/product/showcases/index.vue +86 -0
- package/app/pages/shipment/[...id].vue +176 -0
- package/app/pages/shop/[...slug].vue +158 -0
- package/app/pages/shops.vue +76 -0
- package/app/pages/subscription/[...id].vue +147 -0
- package/app/pages/transaction/[...id].vue +74 -0
- package/app/routes/CategoryPage/CategoryPage.config.ts +28 -0
- package/app/routes/CategoryPage/CategoryPage.type.ts +8 -0
- package/app/routes/Checkout/Checkout.config.ts +3 -0
- package/app/routes/Checkout/Checkout.type.ts +14 -0
- package/app/routes/MyAccount/MyAccount.config.ts +1 -0
- package/app/routes/SearchPage/SearchPage.config.ts +1 -0
- package/app/routes/UrlRewrites/UrlRewrites.config.ts +5 -0
- package/app/stores/Cart/Cart.type.ts +26 -0
- package/app/stores/MyAccount/MyAccount.action.ts +7 -0
- package/app/stores/Notification/Notification.action.ts +40 -0
- package/app/stores/Notification/Notification.type.ts +16 -0
- package/app/stores/Popup/Popup.action.ts +30 -0
- package/app/stores/Product/Product.dispatcher.ts +53 -0
- package/app/stores/Product/Product.reducer.ts +12 -0
- package/app/stores/ProductList/ProductList.dispatcher.ts +35 -0
- package/app/stores/ProductList/ProductList.reducer.ts +13 -0
- package/app/stores/Store.type.ts +31 -0
- package/app/stores/Wishlist/Wishlist.type.ts +12 -0
- package/app/stores/cart.ts +218 -0
- package/app/stores/cartStore.ts +224 -0
- package/app/stores/checkout.ts +18 -0
- package/app/stores/compare.ts +65 -0
- package/app/stores/currency.js +29 -0
- package/app/stores/digital-products.js +11 -0
- package/app/stores/orders.ts +172 -0
- package/app/stores/product.ts +34 -0
- package/app/stores/productList.ts +35 -0
- package/app/stores/productListInfo.ts +0 -0
- package/app/stores/products.ts +118 -0
- package/app/stores/recentlyViewedProducts.ts +56 -0
- package/app/stores/review.ts +33 -0
- package/app/stores/storeInPickUp.ts +21 -0
- package/app/stores/user.ts +20 -0
- package/app/stores/wishlist.ts +46 -0
- package/app/types/Account.type.ts +141 -0
- package/app/types/Breadcrumbs.type.ts +23 -0
- package/app/types/CMS.type.ts +33 -0
- package/app/types/Category.type.ts +67 -0
- package/app/types/Checkout.type.ts +58 -0
- package/app/types/Common.type.ts +77 -0
- package/app/types/Config.type.ts +47 -0
- package/app/types/Device.type.ts +37 -0
- package/app/types/Direction.type.ts +23 -0
- package/app/types/Downloadable.type.ts +24 -0
- package/app/types/Error.type.ts +22 -0
- package/app/types/Field.type.ts +151 -0
- package/app/types/Global.type.ts +156 -0
- package/app/types/Graphql.type.ts +4497 -0
- package/app/types/Layout.type.ts +18 -0
- package/app/types/Menu.type.ts +39 -0
- package/app/types/MiniCart.type.ts +61 -0
- package/app/types/NotificationList.type.ts +34 -0
- package/app/types/Order.type.ts +174 -0
- package/app/types/Price.type.ts +72 -0
- package/app/types/ProductCompare.type.ts +24 -0
- package/app/types/ProductList.type.ts +351 -0
- package/app/types/Rating.type.ts +42 -0
- package/app/types/Router.type.ts +67 -0
- package/app/types/Slider.type.ts +25 -0
- package/app/types/StockStatus.type.ts +21 -0
- package/app/types/domain/index.ts +94 -0
- package/app/types/index.ts +33 -0
- package/app/types/shims.d.ts +52 -0
- package/app/types/tilework-opus.d.ts +48 -0
- package/app/utils/Address/Address.type.ts +28 -0
- package/app/utils/Address/index.ts +325 -0
- package/app/utils/Auth/IsSignedIn.ts +4 -0
- package/app/utils/Auth/Token.ts +9 -0
- package/app/utils/Base64/Base64.ts +16 -0
- package/app/utils/Base64/index.ts +12 -0
- package/app/utils/Browser/Browser.ts +29 -0
- package/app/utils/Browser/index.ts +12 -0
- package/app/utils/BrowserDatabase/BrowserDatabase.ts +70 -0
- package/app/utils/BrowserDatabase/index.ts +12 -0
- package/app/utils/CSS/CSS.ts +65 -0
- package/app/utils/CSS/index.ts +12 -0
- package/app/utils/Cache/Cache.ts +99 -0
- package/app/utils/Cart/Cart.ts +300 -0
- package/app/utils/Cart/Cart.type.ts +76 -0
- package/app/utils/Cart/Token.ts +59 -0
- package/app/utils/Cart/index.ts +13 -0
- package/app/utils/Category/Filters.ts +39 -0
- package/app/utils/Category/index.ts +12 -0
- package/app/utils/Common/index.ts +32 -0
- package/app/utils/Compare/Compare.ts +89 -0
- package/app/utils/Compare/index.ts +12 -0
- package/app/utils/Currency/Currency.ts +84 -0
- package/app/utils/Currency/index.ts +12 -0
- package/app/utils/DynamicReducer/DynamicReducer.type.ts +14 -0
- package/app/utils/DynamicReducer/Helper.ts +30 -0
- package/app/utils/DynamicReducer/index.tsx +35 -0
- package/app/utils/ElementTransition/ElementTransition.ts +100 -0
- package/app/utils/Form/Extract.ts +316 -0
- package/app/utils/Form/Form.ts +46 -0
- package/app/utils/Form/Form.type.ts +60 -0
- package/app/utils/Form/Transform.ts +33 -0
- package/app/utils/FormPortalCollector/index.ts +45 -0
- package/app/utils/History/History.type.ts +31 -0
- package/app/utils/History/index.ts +17 -0
- package/app/utils/Manipulations/Array.ts +18 -0
- package/app/utils/Manipulations/Date.ts +36 -0
- package/app/utils/Manipulations/index.ts +14 -0
- package/app/utils/Media/Media.ts +27 -0
- package/app/utils/Media/index.ts +13 -0
- package/app/utils/Menu/Menu.ts +116 -0
- package/app/utils/Menu/Menu.type.ts +37 -0
- package/app/utils/Menu/index.ts +12 -0
- package/app/utils/Mobile/index.ts +13 -0
- package/app/utils/Mobile/isMobile.ts +34 -0
- package/app/utils/Orders/Orders.ts +71 -0
- package/app/utils/Orders/Orders.type.ts +19 -0
- package/app/utils/Orders/index.ts +13 -0
- package/app/utils/Polyfill/index.ts +336 -0
- package/app/utils/Preload/CategoryPreload.ts +74 -0
- package/app/utils/Preload/ProductPreload.ts +28 -0
- package/app/utils/Preload/index.ts +75 -0
- package/app/utils/Price/Price.config.ts +189 -0
- package/app/utils/Price/Price.ts +63 -0
- package/app/utils/Price/index.ts +12 -0
- package/app/utils/Product/Extract.ts +652 -0
- package/app/utils/Product/Product.ts +575 -0
- package/app/utils/Product/Product.type.ts +260 -0
- package/app/utils/Product/Transform.ts +382 -0
- package/app/utils/Product/index.ts +12 -0
- package/app/utils/Promise/MakeCancelable.ts +44 -0
- package/app/utils/Promise/Promise.type.ts +15 -0
- package/app/utils/Promise/index.ts +13 -0
- package/app/utils/Query/Field.ts +71 -0
- package/app/utils/Query/Fragment.ts +22 -0
- package/app/utils/Query/PrepareDocument.ts +119 -0
- package/app/utils/Query/Query.type.ts +26 -0
- package/app/utils/Query/index.ts +15 -0
- package/app/utils/Request/Config.ts +21 -0
- package/app/utils/Request/DataContainer.ts +102 -0
- package/app/utils/Request/Debounce.ts +48 -0
- package/app/utils/Request/Error.ts +31 -0
- package/app/utils/Request/Hash.ts +88 -0
- package/app/utils/Request/LowPriorityLoad.ts +32 -0
- package/app/utils/Request/LowPriorityRender.ts +55 -0
- package/app/utils/Request/Mutation.ts +25 -0
- package/app/utils/Request/Query.ts +25 -0
- package/app/utils/Request/QueryDispatcher.ts +135 -0
- package/app/utils/Request/Request.ts +310 -0
- package/app/utils/Store/Store.type.ts +26 -0
- package/app/utils/Store/index.ts +71 -0
- package/app/utils/Url/Url.ts +297 -0
- package/app/utils/Url/index.ts +12 -0
- package/app/utils/Validator/Config.ts +96 -0
- package/app/utils/Validator/Validator.ts +268 -0
- package/app/utils/Validator/Validator.type.ts +47 -0
- package/app/utils/Validator/index.ts +12 -0
- package/app/utils/Wishlist/Wishlist.ts +65 -0
- package/app/utils/Wishlist/index.ts +12 -0
- package/app/utils/client.ts +280 -0
- package/app/utils/index.ts +53 -0
- package/app/utils/normalizer.ts +23 -0
- package/app/utils/normalizers/magento.ts +29 -0
- package/app/utils/normalizers/shopify.ts +29 -0
- package/nuxt.config.ts +11 -0
- package/package.json +43 -0
- package/tsconfig.json +45 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getCommerceClient } from '../../utils/client'
|
|
2
|
+
|
|
3
|
+
// Product dispatcher that uses the normalized commerce client when available.
|
|
4
|
+
export async function fetchProductById(id: string): Promise<any | null> {
|
|
5
|
+
try {
|
|
6
|
+
const client = getCommerceClient()
|
|
7
|
+
if (client) {
|
|
8
|
+
if (typeof client.getProductById === 'function') return await client.getProductById(id)
|
|
9
|
+
if (typeof client.getProduct === 'function') return await client.getProduct(id)
|
|
10
|
+
if (typeof client.getProducts === 'function') {
|
|
11
|
+
const list = await client.getProducts({ ids: [id] })
|
|
12
|
+
return Array.isArray(list) ? list.find((p: any) => p.id === id || p.sku === id) ?? null : null
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
} catch (e) {
|
|
16
|
+
console.error('fetchProductById failed:', e)
|
|
17
|
+
}
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function fetchProductVariants(productId: string): Promise<any[]> {
|
|
22
|
+
try {
|
|
23
|
+
const client = getCommerceClient()
|
|
24
|
+
if (client && typeof client.getProductVariants === 'function') {
|
|
25
|
+
return await client.getProductVariants(productId)
|
|
26
|
+
}
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error('fetchProductVariants failed:', e)
|
|
29
|
+
}
|
|
30
|
+
return []
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function handleData(dispatch: any, options: any) {
|
|
34
|
+
// If a preload system passes a dispatch function and product id, load product and dispatch
|
|
35
|
+
try {
|
|
36
|
+
if (typeof dispatch === 'function' && options && options.id) {
|
|
37
|
+
const product = await fetchProductById(options.id)
|
|
38
|
+
dispatch({ type: 'PRODUCT_LOADED', payload: product })
|
|
39
|
+
return product
|
|
40
|
+
}
|
|
41
|
+
} catch (e) {
|
|
42
|
+
// ignore
|
|
43
|
+
}
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const _default = {
|
|
48
|
+
fetchProductById,
|
|
49
|
+
fetchProductVariants,
|
|
50
|
+
handleData,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export default _default
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Minimal Product reducer compatibility layer. Responds to `PRODUCT_LOADED`.
|
|
2
|
+
export default function ProductReducer(state = { product: null }, action: any) {
|
|
3
|
+
if (!action) return state
|
|
4
|
+
try {
|
|
5
|
+
if (action.type === 'PRODUCT_LOADED') {
|
|
6
|
+
return { ...state, product: action.payload }
|
|
7
|
+
}
|
|
8
|
+
} catch (e) {
|
|
9
|
+
// ignore and return current state
|
|
10
|
+
}
|
|
11
|
+
return state
|
|
12
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getCommerceClient } from '../../utils/client'
|
|
2
|
+
|
|
3
|
+
// ProductList dispatcher that prefers the normalized commerce client when
|
|
4
|
+
// available. Returns an array of normalized products or an empty array.
|
|
5
|
+
export async function fetchProductList(params: any = {}): Promise<any[]> {
|
|
6
|
+
const client = getCommerceClient()
|
|
7
|
+
try {
|
|
8
|
+
if (client) {
|
|
9
|
+
if (typeof client.listProducts === 'function') {
|
|
10
|
+
return await client.listProducts(params)
|
|
11
|
+
}
|
|
12
|
+
if (typeof client.getProducts === 'function') {
|
|
13
|
+
return await client.getProducts(params)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
} catch (e) {
|
|
17
|
+
console.error('fetchProductList failed:', e)
|
|
18
|
+
}
|
|
19
|
+
return []
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function handleData(dispatch: any, options: any) {
|
|
23
|
+
const data = await fetchProductList(options)
|
|
24
|
+
if (typeof dispatch === 'function') {
|
|
25
|
+
try {
|
|
26
|
+
dispatch({ type: 'PRODUCT_LIST_LOADED', payload: data })
|
|
27
|
+
} catch (e) {
|
|
28
|
+
// best-effort: ignore dispatch errors
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return data
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const _default = { fetchProductList, handleData }
|
|
35
|
+
export default _default
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Minimal ProductList reducer compatibility layer. Accepts an action with
|
|
2
|
+
// `type: 'PRODUCT_LIST_LOADED'` and `payload` to populate `items`.
|
|
3
|
+
export default function ProductListReducer(state = { items: [] }, action: any) {
|
|
4
|
+
if (!action) return state
|
|
5
|
+
try {
|
|
6
|
+
if (action.type === 'PRODUCT_LIST_LOADED') {
|
|
7
|
+
return { ...state, items: Array.isArray(action.payload) ? action.payload : state.items }
|
|
8
|
+
}
|
|
9
|
+
} catch (e) {
|
|
10
|
+
// ignore and return current state
|
|
11
|
+
}
|
|
12
|
+
return state
|
|
13
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Minimal RootState shim to satisfy legacy reducer shape references.
|
|
2
|
+
// Keep it permissive: callers may rely on additional keys at runtime.
|
|
3
|
+
export interface ConfigReducerState {
|
|
4
|
+
countries?: any[]
|
|
5
|
+
base_link_url?: string
|
|
6
|
+
secure_base_media_url?: string
|
|
7
|
+
base_url?: string
|
|
8
|
+
[key: string]: any
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface CartReducerState {
|
|
12
|
+
cart?: any
|
|
13
|
+
items?: any[]
|
|
14
|
+
totals?: any
|
|
15
|
+
[key: string]: any
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface MyAccountReducerState {
|
|
19
|
+
customer?: any
|
|
20
|
+
signedIn?: boolean
|
|
21
|
+
[key: string]: any
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface RootState {
|
|
25
|
+
ConfigReducer?: ConfigReducerState
|
|
26
|
+
CartReducer?: CartReducerState
|
|
27
|
+
MyAccountReducer?: MyAccountReducerState
|
|
28
|
+
[key: string]: any
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Named interface `RootState` exported above; no additional export statement needed.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { ref, computed, readonly } from 'vue'
|
|
2
|
+
import type { Cart as DomainCart } from '../types/domain'
|
|
3
|
+
import { useCart } from '../cart/useCart'
|
|
4
|
+
import { defineStore } from 'pinia'
|
|
5
|
+
|
|
6
|
+
export const useCartStore = defineStore('cart', () => {
|
|
7
|
+
const cart = ref<DomainCart | null>(null)
|
|
8
|
+
const loading = ref(false)
|
|
9
|
+
const error = ref<string | null>(null)
|
|
10
|
+
|
|
11
|
+
// Import cart composable
|
|
12
|
+
const {
|
|
13
|
+
fetchCart,
|
|
14
|
+
addToCart,
|
|
15
|
+
removeFromCart,
|
|
16
|
+
updateCartItem,
|
|
17
|
+
applyCoupon,
|
|
18
|
+
removeCoupon,
|
|
19
|
+
clearCart,
|
|
20
|
+
setShippingOption: setShippingOptionFn
|
|
21
|
+
,createCheckoutSession: createCheckoutSessionFn
|
|
22
|
+
} = useCart() as any
|
|
23
|
+
|
|
24
|
+
const initializeCart = async () => {
|
|
25
|
+
loading.value = true
|
|
26
|
+
error.value = null
|
|
27
|
+
try {
|
|
28
|
+
await fetchCart()
|
|
29
|
+
} catch (err: any) {
|
|
30
|
+
error.value = err.message
|
|
31
|
+
console.error('Error initializing cart:', err)
|
|
32
|
+
} finally {
|
|
33
|
+
loading.value = false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const addProductToCart = async (productId: string, quantity: number = 1, variantId?: string) => {
|
|
38
|
+
loading.value = true
|
|
39
|
+
error.value = null
|
|
40
|
+
try {
|
|
41
|
+
await addToCart(productId, quantity, variantId)
|
|
42
|
+
} catch (err: any) {
|
|
43
|
+
error.value = err.message
|
|
44
|
+
console.error('Error adding product to cart:', err)
|
|
45
|
+
throw err
|
|
46
|
+
} finally {
|
|
47
|
+
loading.value = false
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const removeProductFromCart = async (itemId: string) => {
|
|
52
|
+
loading.value = true
|
|
53
|
+
error.value = null
|
|
54
|
+
try {
|
|
55
|
+
await removeFromCart(itemId)
|
|
56
|
+
} catch (err: any) {
|
|
57
|
+
error.value = err.message
|
|
58
|
+
console.error('Error removing product from cart:', err)
|
|
59
|
+
throw err
|
|
60
|
+
} finally {
|
|
61
|
+
loading.value = false
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const updateProductQuantity = async (itemId: string, quantity: number) => {
|
|
66
|
+
loading.value = true
|
|
67
|
+
error.value = null
|
|
68
|
+
try {
|
|
69
|
+
await updateCartItem(itemId, quantity)
|
|
70
|
+
} catch (err: any) {
|
|
71
|
+
error.value = err.message
|
|
72
|
+
console.error('Error updating cart item:', err)
|
|
73
|
+
throw err
|
|
74
|
+
} finally {
|
|
75
|
+
loading.value = false
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const applyCartCoupon = async (couponCode: string) => {
|
|
80
|
+
loading.value = true
|
|
81
|
+
error.value = null
|
|
82
|
+
try {
|
|
83
|
+
const success = await applyCoupon(couponCode)
|
|
84
|
+
if (!success) {
|
|
85
|
+
throw new Error('Failed to apply coupon')
|
|
86
|
+
}
|
|
87
|
+
} catch (err: any) {
|
|
88
|
+
error.value = err.message
|
|
89
|
+
console.error('Error applying coupon:', err)
|
|
90
|
+
throw err
|
|
91
|
+
} finally {
|
|
92
|
+
loading.value = false
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const removeCartCoupon = async () => {
|
|
97
|
+
loading.value = true
|
|
98
|
+
error.value = null
|
|
99
|
+
try {
|
|
100
|
+
await removeCoupon()
|
|
101
|
+
} catch (err: any) {
|
|
102
|
+
error.value = err.message
|
|
103
|
+
console.error('Error removing coupon:', err)
|
|
104
|
+
throw err
|
|
105
|
+
} finally {
|
|
106
|
+
loading.value = false
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const emptyCart = async () => {
|
|
111
|
+
loading.value = true
|
|
112
|
+
error.value = null
|
|
113
|
+
try {
|
|
114
|
+
await clearCart()
|
|
115
|
+
} catch (err: any) {
|
|
116
|
+
error.value = err.message
|
|
117
|
+
console.error('Error clearing cart:', err)
|
|
118
|
+
throw err
|
|
119
|
+
} finally {
|
|
120
|
+
loading.value = false
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const setShippingOption = async (option: any) => {
|
|
125
|
+
loading.value = true
|
|
126
|
+
error.value = null
|
|
127
|
+
try {
|
|
128
|
+
if (!setShippingOptionFn) throw new Error('Shipping setter unavailable')
|
|
129
|
+
await setShippingOptionFn(option)
|
|
130
|
+
} catch (err: any) {
|
|
131
|
+
error.value = err.message
|
|
132
|
+
console.error('Error setting shipping option:', err)
|
|
133
|
+
throw err
|
|
134
|
+
} finally {
|
|
135
|
+
loading.value = false
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const createCheckoutSession = async (cartId?: string) => {
|
|
140
|
+
loading.value = true
|
|
141
|
+
error.value = null
|
|
142
|
+
try {
|
|
143
|
+
const data = await createCheckoutSessionFn(cartId)
|
|
144
|
+
return data
|
|
145
|
+
} catch (err: any) {
|
|
146
|
+
error.value = err.message
|
|
147
|
+
throw err
|
|
148
|
+
} finally {
|
|
149
|
+
loading.value = false
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Computed properties
|
|
154
|
+
const itemCount = computed(() => {
|
|
155
|
+
return cart.value?.items?.reduce((count: number, item: any) => count + (item?.quantity ?? 0), 0) || 0
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
const isEmpty = computed(() => {
|
|
159
|
+
return !cart.value?.items?.length
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
const hasItems = computed(() => {
|
|
163
|
+
return !isEmpty.value
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
const subtotal = computed(() => {
|
|
167
|
+
return (cart.value?.prices?.subtotal?.value ?? (cart.value as any)?.subtotal ?? 0) as number
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
const total = computed(() => {
|
|
171
|
+
return (cart.value?.prices?.grand_total?.value ?? (cart.value as any)?.total ?? 0) as number
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
const taxAmount = computed(() => {
|
|
175
|
+
return (cart.value?.prices?.tax?.value ?? (cart.value as any)?.tax_amount ?? 0) as number
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
const shippingAmount = computed(() => {
|
|
179
|
+
return (cart.value?.prices?.shipping?.value ?? (cart.value as any)?.shipping_amount ?? 0) as number
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
const discountAmount = computed(() => {
|
|
183
|
+
return (cart.value?.prices?.discounts?.value ?? (cart.value as any)?.discount_amount ?? 0) as number
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
const hasCoupon = computed(() => {
|
|
187
|
+
return !!(cart.value as any)?.coupon_code
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
// State
|
|
192
|
+
cart: readonly(cart),
|
|
193
|
+
loading: readonly(loading),
|
|
194
|
+
error: readonly(error),
|
|
195
|
+
|
|
196
|
+
// Computed
|
|
197
|
+
itemCount,
|
|
198
|
+
isEmpty,
|
|
199
|
+
hasItems,
|
|
200
|
+
subtotal,
|
|
201
|
+
total,
|
|
202
|
+
taxAmount,
|
|
203
|
+
shippingAmount,
|
|
204
|
+
discountAmount,
|
|
205
|
+
hasCoupon,
|
|
206
|
+
|
|
207
|
+
// Actions
|
|
208
|
+
initializeCart,
|
|
209
|
+
addProductToCart,
|
|
210
|
+
removeProductFromCart,
|
|
211
|
+
updateProductQuantity,
|
|
212
|
+
applyCartCoupon,
|
|
213
|
+
removeCartCoupon,
|
|
214
|
+
emptyCart
|
|
215
|
+
,setShippingOption
|
|
216
|
+
,createCheckoutSession
|
|
217
|
+
}
|
|
218
|
+
})
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
// stores/cartStore.ts
|
|
2
|
+
import { defineStore } from 'pinia'
|
|
3
|
+
import { getCommerceClient } from '../utils/client'
|
|
4
|
+
import { useAuth } from '../composables/useAuth'
|
|
5
|
+
import { useInventory } from '../composables/useInventory'
|
|
6
|
+
import { useTax } from '../composables/useTax'
|
|
7
|
+
import { useLoading } from '../composables/useLoading'
|
|
8
|
+
import { useNotification } from '../composables/useNotification'
|
|
9
|
+
import { useCache } from '../composables/useCache'
|
|
10
|
+
|
|
11
|
+
class CartError extends Error {
|
|
12
|
+
code: string
|
|
13
|
+
constructor(message: string, code: string) {
|
|
14
|
+
super(message)
|
|
15
|
+
this.code = code
|
|
16
|
+
this.name = 'CartError'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface CartProduct {
|
|
21
|
+
sku: string
|
|
22
|
+
name?: string
|
|
23
|
+
price?: number
|
|
24
|
+
qty: number
|
|
25
|
+
quote_id?: string
|
|
26
|
+
item_id?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const useCartStore = defineStore('cart', {
|
|
30
|
+
state: () => ({
|
|
31
|
+
isGuest: true,
|
|
32
|
+
items: [] as CartProduct[],
|
|
33
|
+
total: 0,
|
|
34
|
+
quoteId: null as string | null,
|
|
35
|
+
client: getCommerceClient()
|
|
36
|
+
}),
|
|
37
|
+
|
|
38
|
+
actions: {
|
|
39
|
+
async initializeCart() {
|
|
40
|
+
const auth = useAuth()
|
|
41
|
+
this.isGuest = !auth.token.value
|
|
42
|
+
try {
|
|
43
|
+
if (this.isGuest) await this.createGuestCart()
|
|
44
|
+
else await this.createCustomerCart()
|
|
45
|
+
} catch (err) {
|
|
46
|
+
console.error(err)
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
async createGuestCart() {
|
|
51
|
+
try {
|
|
52
|
+
if (this.client && typeof this.client.createGuestCart === 'function') {
|
|
53
|
+
this.quoteId = await this.client.createGuestCart()
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
const response = await fetch(`${process.env.MAGENTO_API_URL}/guest-carts`, { method: 'POST' })
|
|
57
|
+
this.quoteId = (await response.json()) as string
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.error(err)
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
async createCustomerCart() {
|
|
64
|
+
try {
|
|
65
|
+
const auth = useAuth()
|
|
66
|
+
if (this.client && typeof this.client.createCustomerCart === 'function') {
|
|
67
|
+
this.quoteId = await this.client.createCustomerCart(auth.token?.value)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
const response = await fetch(`${process.env.MAGENTO_API_URL}/carts/mine`, {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
headers: { Authorization: `Bearer ${auth.token.value}` }
|
|
73
|
+
})
|
|
74
|
+
this.quoteId = await response.json()
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.error(err)
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
async addItem(product: CartProduct) {
|
|
81
|
+
const loading = useLoading()
|
|
82
|
+
loading.startLoading('Adding to cart...')
|
|
83
|
+
try {
|
|
84
|
+
const auth = useAuth()
|
|
85
|
+
if (auth.isTokenExpired()) await auth.refreshAccessToken()
|
|
86
|
+
const inventory = useInventory()
|
|
87
|
+
await inventory.checkInventory(product.sku, product.qty)
|
|
88
|
+
if (!this.quoteId) await this.initializeCart()
|
|
89
|
+
if (!this.quoteId) throw new CartError('Failed to create cart', 'CART_ERROR')
|
|
90
|
+
|
|
91
|
+
if (this.client && typeof this.client.addItem === 'function') {
|
|
92
|
+
const cartItem = await this.client.addItem(this.quoteId, product, auth.token?.value)
|
|
93
|
+
const existing = this.items.find(i => i.sku === product.sku)
|
|
94
|
+
if (existing) existing.qty += product.qty
|
|
95
|
+
else this.items.push({ ...product, item_id: cartItem?.item_id })
|
|
96
|
+
} else {
|
|
97
|
+
const response = await fetch(`${process.env.MAGENTO_API_URL}/carts/mine/items`, {
|
|
98
|
+
method: 'POST',
|
|
99
|
+
headers: { Authorization: `Bearer ${auth.token.value}`, 'Content-Type': 'application/json' },
|
|
100
|
+
body: JSON.stringify({ cartItem: { sku: product.sku, qty: product.qty, quote_id: this.quoteId } })
|
|
101
|
+
})
|
|
102
|
+
if (!response.ok) throw new CartError('Failed to add item to cart', 'CART_ERROR')
|
|
103
|
+
const cartItem = await response.json()
|
|
104
|
+
const existing = this.items.find(i => i.sku === product.sku)
|
|
105
|
+
if (existing) existing.qty += product.qty
|
|
106
|
+
else this.items.push({ ...product, item_id: cartItem.item_id })
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const tax = useTax()
|
|
110
|
+
if (this.quoteId) await tax.calculateTax(this.quoteId)
|
|
111
|
+
const cache = useCache()
|
|
112
|
+
cache.setCacheItem(`cart_product_${product.sku}`, product)
|
|
113
|
+
await this.calculateTotal()
|
|
114
|
+
loading.stopLoading()
|
|
115
|
+
useNotification().show({ type: 'success', message: 'Product added to cart' })
|
|
116
|
+
} catch (err) {
|
|
117
|
+
loading.stopLoading()
|
|
118
|
+
console.error(err)
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
async removeItem(itemId: string) {
|
|
123
|
+
const loading = useLoading()
|
|
124
|
+
loading.startLoading('Removing item...')
|
|
125
|
+
try {
|
|
126
|
+
const auth = useAuth()
|
|
127
|
+
if (auth.isTokenExpired()) await auth.refreshAccessToken()
|
|
128
|
+
|
|
129
|
+
if (this.client && typeof this.client.removeItem === 'function') {
|
|
130
|
+
await this.client.removeItem(this.quoteId, itemId, auth.token?.value)
|
|
131
|
+
this.items = this.items.filter(i => i.item_id !== itemId)
|
|
132
|
+
await this.calculateTotal()
|
|
133
|
+
} else {
|
|
134
|
+
const response = await fetch(`${process.env.MAGENTO_API_URL}/carts/mine/items/${itemId}`, { method: 'DELETE', headers: { Authorization: `Bearer ${auth.token.value}` } })
|
|
135
|
+
if (!response.ok) throw new CartError('Failed to remove item from cart', 'CART_ERROR')
|
|
136
|
+
this.items = this.items.filter(i => i.item_id !== itemId)
|
|
137
|
+
await this.calculateTotal()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
loading.stopLoading()
|
|
141
|
+
useNotification().show({ type: 'success', message: 'Item removed from cart' })
|
|
142
|
+
} catch (err) {
|
|
143
|
+
loading.stopLoading()
|
|
144
|
+
console.error(err)
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
async calculateTotal() {
|
|
149
|
+
try {
|
|
150
|
+
const auth = useAuth()
|
|
151
|
+
if (!this.quoteId) return
|
|
152
|
+
if (this.client && typeof this.client.getTotals === 'function') {
|
|
153
|
+
const totals = await this.client.getTotals(this.quoteId, auth.token?.value)
|
|
154
|
+
this.total = totals?.grand_total || 0
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
const response = await fetch(`${process.env.MAGENTO_API_URL}/carts/mine/totals`, { headers: { Authorization: `Bearer ${auth.token.value}` } })
|
|
158
|
+
if (!response.ok) throw new CartError('Failed to get cart totals', 'CART_ERROR')
|
|
159
|
+
const totals = await response.json()
|
|
160
|
+
this.total = totals.grand_total
|
|
161
|
+
} catch (err) {
|
|
162
|
+
console.error('Error calculating totals:', err)
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
async clearCart() {
|
|
167
|
+
const loading = useLoading()
|
|
168
|
+
loading.startLoading('Clearing cart...')
|
|
169
|
+
try {
|
|
170
|
+
const auth = useAuth()
|
|
171
|
+
if (this.quoteId) {
|
|
172
|
+
if (this.client && typeof this.client.clearCart === 'function') {
|
|
173
|
+
await this.client.clearCart(this.quoteId, auth.token?.value)
|
|
174
|
+
} else {
|
|
175
|
+
const response = await fetch(`${process.env.MAGENTO_API_URL}/carts/mine/clear`, { method: 'POST', headers: { Authorization: `Bearer ${auth.token.value}` } })
|
|
176
|
+
if (!response.ok) throw new CartError('Failed to clear cart', 'CART_ERROR')
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
this.items = []
|
|
180
|
+
this.total = 0
|
|
181
|
+
this.quoteId = null
|
|
182
|
+
const cache = useCache()
|
|
183
|
+
this.items.forEach(item => cache.setCacheItem(`cart_product_${item.sku}`, null))
|
|
184
|
+
loading.stopLoading()
|
|
185
|
+
useNotification().show({ type: 'success', message: 'Cart cleared successfully' })
|
|
186
|
+
} catch (err) {
|
|
187
|
+
loading.stopLoading()
|
|
188
|
+
console.error(err)
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
async syncCartWithMagento() {
|
|
193
|
+
try {
|
|
194
|
+
const auth = useAuth()
|
|
195
|
+
if (this.client && typeof this.client.listItems === 'function') {
|
|
196
|
+
this.items = await this.client.listItems(this.quoteId, auth.token?.value)
|
|
197
|
+
await this.calculateTotal()
|
|
198
|
+
return
|
|
199
|
+
}
|
|
200
|
+
const response = await fetch(`${process.env.MAGENTO_API_URL}/carts/mine/items`, { headers: { Authorization: `Bearer ${auth.token.value}` } })
|
|
201
|
+
if (!response.ok) throw new CartError('Failed to sync cart', 'CART_ERROR')
|
|
202
|
+
this.items = await response.json()
|
|
203
|
+
await this.calculateTotal()
|
|
204
|
+
} catch (err) {
|
|
205
|
+
console.error(err)
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
async validateCart() {
|
|
210
|
+
try {
|
|
211
|
+
for (const item of this.items) {
|
|
212
|
+
const inventory = useInventory()
|
|
213
|
+
const isAvailable = await inventory.checkInventory(item.sku, item.qty)
|
|
214
|
+
if (!isAvailable) throw new CartError(`${item.name} is out of stock`, 'INVENTORY_ERROR')
|
|
215
|
+
}
|
|
216
|
+
await this.syncCartWithMagento()
|
|
217
|
+
return true
|
|
218
|
+
} catch (err) {
|
|
219
|
+
console.error(err)
|
|
220
|
+
return false
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
})
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineStore } from 'pinia';
|
|
2
|
+
|
|
3
|
+
export const useCheckoutStore = defineStore('checkout', {
|
|
4
|
+
state: (): { shippingAddress: string | null; paymentMethod: any; orderId: string; isLoading: boolean } => ({
|
|
5
|
+
shippingAddress: null,
|
|
6
|
+
paymentMethod: null,
|
|
7
|
+
orderId: '',
|
|
8
|
+
isLoading: false
|
|
9
|
+
}),
|
|
10
|
+
actions: {
|
|
11
|
+
setShippingAddress(address: string) {
|
|
12
|
+
this.shippingAddress = address;
|
|
13
|
+
},
|
|
14
|
+
setPaymentMethod(method: string) {
|
|
15
|
+
this.paymentMethod = method;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// stores/compare.ts
|
|
2
|
+
import { defineStore } from 'pinia';
|
|
3
|
+
import type {
|
|
4
|
+
ComparableAttribute,
|
|
5
|
+
ComparableItem,
|
|
6
|
+
ComparableProduct,
|
|
7
|
+
CompareList,
|
|
8
|
+
} from '~/types/ProductCompare.type';
|
|
9
|
+
|
|
10
|
+
export const useCompareStore = defineStore('compare', {
|
|
11
|
+
state: () => ({
|
|
12
|
+
isLoading: false,
|
|
13
|
+
count: 0,
|
|
14
|
+
attributes: [] as ComparableAttribute[],
|
|
15
|
+
products: [] as ComparableProduct[],
|
|
16
|
+
productSkus: [] as string[],
|
|
17
|
+
items: [] as ComparableItem[]
|
|
18
|
+
}),
|
|
19
|
+
|
|
20
|
+
actions: {
|
|
21
|
+
toggleLoader(isLoading: boolean) {
|
|
22
|
+
this.isLoading = isLoading;
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
setCompareList(payload: CompareList) {
|
|
26
|
+
this.attributes = payload.attributes || [];
|
|
27
|
+
this.products = payload.products || [];
|
|
28
|
+
this.items = payload.items || [];
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
removeComparedProduct(productSku: string) {
|
|
32
|
+
this.products = this.products.filter((product: any) => product.sku !== productSku);
|
|
33
|
+
this.productSkus = this.productSkus.filter((sku: string) => sku !== productSku);
|
|
34
|
+
this.items = this.items.filter((item: any) => item.product.sku !== productSku);
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
clearComparedProducts() {
|
|
38
|
+
this.products = [];
|
|
39
|
+
this.productSkus = [];
|
|
40
|
+
this.items = [];
|
|
41
|
+
this.count = 0;
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
setCompareListSkus(productSkus: string[]) {
|
|
45
|
+
this.productSkus = productSkus;
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
addComparedProductSku(productSku: string) {
|
|
49
|
+
if (!this.productSkus.includes(productSku)) {
|
|
50
|
+
this.productSkus.push(productSku);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
updateCompareTotals(compareTotals: string) {
|
|
55
|
+
this.count = parseInt(compareTotals, 10); // Convert string to number
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
getters: {
|
|
60
|
+
getCompareCount: (state) => state.count,
|
|
61
|
+
getComparedProducts: (state) => state.products,
|
|
62
|
+
getComparedProductSkus: (state) => state.productSkus,
|
|
63
|
+
getIsLoading: (state) => state.isLoading
|
|
64
|
+
}
|
|
65
|
+
});
|