@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,37 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
name: 'Smartwatch Fitness Tracker',
|
|
3
|
+
quantity: 1,
|
|
4
|
+
price: {
|
|
5
|
+
value: {
|
|
6
|
+
currency: 'Dollar',
|
|
7
|
+
amount: 295.87,
|
|
8
|
+
precisionAmount: '295.87',
|
|
9
|
+
},
|
|
10
|
+
isDiscounted: false,
|
|
11
|
+
regularPrice: {
|
|
12
|
+
currency: 'Dollar',
|
|
13
|
+
amount: 295.87,
|
|
14
|
+
precisionAmount: '295.87',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
gallery: [
|
|
18
|
+
{
|
|
19
|
+
alt: 'Smartwatch Fitness Tracker',
|
|
20
|
+
url: '/images/watch.png',
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
attributes: [
|
|
24
|
+
{
|
|
25
|
+
label: 'Size',
|
|
26
|
+
name: 'Size',
|
|
27
|
+
value: '1.9″',
|
|
28
|
+
valueLabel: 'value',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'Color',
|
|
32
|
+
label: 'color',
|
|
33
|
+
value: 'Black',
|
|
34
|
+
valueLabel: 'value',
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
import type { Maybe, SfAddress, SfProduct } from '../_types';
|
|
3
|
+
|
|
4
|
+
export type OrderData = {
|
|
5
|
+
id: string;
|
|
6
|
+
date: string; //probably should be number in ms
|
|
7
|
+
paymentAmount: number;
|
|
8
|
+
status: 'Completed' | 'Shipped' | 'Open' | 'Cancelled';
|
|
9
|
+
products: Array<
|
|
10
|
+
Omit<
|
|
11
|
+
SfProduct,
|
|
12
|
+
'id' | 'sku' | 'slug' | 'description' | 'primaryImage' | 'rating' | 'variants' | 'quantityLimit'
|
|
13
|
+
> & { quantity: number }
|
|
14
|
+
>;
|
|
15
|
+
summary: {
|
|
16
|
+
subtotal: number;
|
|
17
|
+
delivery: number;
|
|
18
|
+
estimatedTax: number;
|
|
19
|
+
total: number;
|
|
20
|
+
};
|
|
21
|
+
billingAddress: Partial<SfAddress>;
|
|
22
|
+
shippingAddress: Partial<SfAddress>;
|
|
23
|
+
paymentMethod: string;
|
|
24
|
+
shipping: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export interface UseCustomerOrderState {
|
|
28
|
+
data: Maybe<OrderData>;
|
|
29
|
+
loading: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type FetchCustomerOrder = (id: string) => Promise<Ref<Maybe<OrderData>>>;
|
|
33
|
+
|
|
34
|
+
export interface UseCustomerOrder {
|
|
35
|
+
data: Readonly<Ref<UseCustomerOrderState['data']>>;
|
|
36
|
+
loading: Readonly<Ref<boolean>>;
|
|
37
|
+
fetchCustomerOrder: FetchCustomerOrder;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type UseCustomerOrderReturn = (id: string) => UseCustomerOrder;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { toRefs } from '@vueuse/shared';
|
|
2
|
+
import addressData from './adress';
|
|
3
|
+
import productData from './product';
|
|
4
|
+
import type {
|
|
5
|
+
UseCustomerOrderReturn,
|
|
6
|
+
UseCustomerOrderState,
|
|
7
|
+
FetchCustomerOrder,
|
|
8
|
+
OrderData,
|
|
9
|
+
} from './types';
|
|
10
|
+
import { useAsyncData, useState } from 'nuxt/app';
|
|
11
|
+
import { useHandleError } from '../useHandleError';
|
|
12
|
+
|
|
13
|
+
const order: OrderData = {
|
|
14
|
+
id: '0e4fec5a-61e6-48b8-94cc-d5f77687e2b0',
|
|
15
|
+
date: '2022-08-11',
|
|
16
|
+
paymentAmount: 295.87,
|
|
17
|
+
paymentMethod: 'Credit Card',
|
|
18
|
+
shipping: 'Standard (FREE)',
|
|
19
|
+
summary: {
|
|
20
|
+
subtotal: 7037.99,
|
|
21
|
+
delivery: 0,
|
|
22
|
+
estimatedTax: 457.47,
|
|
23
|
+
total: 295.87,
|
|
24
|
+
},
|
|
25
|
+
billingAddress: addressData,
|
|
26
|
+
shippingAddress: addressData,
|
|
27
|
+
status: 'Completed',
|
|
28
|
+
products: [productData, productData],
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
|
|
32
|
+
const getCustomerOrder = (id: string) => order;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @description Composable managing customer order data
|
|
36
|
+
* @returns {@link UseCustomerOrderReturn}
|
|
37
|
+
* @example
|
|
38
|
+
* const { data, loading, fetchCustomerOrder } = useCustomerOrder();
|
|
39
|
+
*/
|
|
40
|
+
export const useCustomerOrder: UseCustomerOrderReturn = (id) => {
|
|
41
|
+
const state = useState<UseCustomerOrderState>(`useCustomerOrder-${id}`, () => ({
|
|
42
|
+
data: null,
|
|
43
|
+
loading: false,
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
/** Function for fetching customer order data
|
|
47
|
+
* @example
|
|
48
|
+
* fetchCustomerOrder();
|
|
49
|
+
*/
|
|
50
|
+
const fetchCustomerOrder: FetchCustomerOrder = async (id) => {
|
|
51
|
+
state.value.loading = true;
|
|
52
|
+
const { data, error } = await useAsyncData(() => Promise.resolve(getCustomerOrder(id)));
|
|
53
|
+
useHandleError(error.value);
|
|
54
|
+
state.value.data = data.value;
|
|
55
|
+
state.value.loading = false;
|
|
56
|
+
return data as unknown as ReturnType<FetchCustomerOrder>;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
fetchCustomerOrder,
|
|
61
|
+
...toRefs(state.value),
|
|
62
|
+
};
|
|
63
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useCustomerOrders } from '~/composables/useCustomerOrders/useCustomerOrders';
|
|
2
|
+
|
|
3
|
+
describe('useCustomerOrders', () => {
|
|
4
|
+
it('should return customer orders data', async () => {
|
|
5
|
+
const { fetchCustomerOrders, data } = useCustomerOrders();
|
|
6
|
+
|
|
7
|
+
await fetchCustomerOrders();
|
|
8
|
+
|
|
9
|
+
expect(data.value).not.toBeUndefined();
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
import type { Maybe } from '../_types';
|
|
3
|
+
import type { OrderData } from '../useCustomerOrder/types';
|
|
4
|
+
|
|
5
|
+
export type OrdersData = Pick<OrderData, 'id' | 'date' | 'paymentAmount' | 'status'>[];
|
|
6
|
+
|
|
7
|
+
export interface UseCustomerOrdersState {
|
|
8
|
+
data: Maybe<OrdersData>;
|
|
9
|
+
loading: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type FetchCustomerOrders = () => Promise<Ref<Maybe<OrdersData>>>;
|
|
13
|
+
|
|
14
|
+
export interface UseCustomerOrders {
|
|
15
|
+
data: Readonly<Ref<UseCustomerOrdersState['data']>>;
|
|
16
|
+
loading: Readonly<Ref<boolean>>;
|
|
17
|
+
fetchCustomerOrders: FetchCustomerOrders;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type UseCustomerOrdersReturn = () => UseCustomerOrders;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { toRefs } from '@vueuse/shared';
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import type { Ref } from 'vue';
|
|
4
|
+
import type { Maybe } from '../_types';
|
|
5
|
+
import type { OrderData } from '../useCustomerOrder/types';
|
|
6
|
+
import type {
|
|
7
|
+
UseCustomerOrdersReturn,
|
|
8
|
+
UseCustomerOrdersState,
|
|
9
|
+
FetchCustomerOrders,
|
|
10
|
+
OrdersData,
|
|
11
|
+
} from './types';
|
|
12
|
+
import { useAsyncData, useState } from 'nuxt/app';
|
|
13
|
+
import { useHandleError } from '../useHandleError';
|
|
14
|
+
|
|
15
|
+
const order: Pick<OrderData, 'id' | 'date' | 'paymentAmount'> = {
|
|
16
|
+
id: '0e4fec5a-61e6-48b8-94cc-d5f77687e2b0',
|
|
17
|
+
date: '2022-08-11',
|
|
18
|
+
paymentAmount: 295.87,
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* @description Composable managing customer orders data
|
|
22
|
+
* @returns {@link UseCustomerOrdersReturn}
|
|
23
|
+
* @example
|
|
24
|
+
* const { data, loading, fetchCustomerOrders } = useCustomerOrders();
|
|
25
|
+
*/
|
|
26
|
+
export const useCustomerOrders: UseCustomerOrdersReturn = () => {
|
|
27
|
+
const state = useState<UseCustomerOrdersState>('useCustomerOrders', () => ({
|
|
28
|
+
data: null,
|
|
29
|
+
loading: false,
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
/** Function for fetching customer orders data
|
|
33
|
+
* @example
|
|
34
|
+
* fetchCustomerOrders();
|
|
35
|
+
*/
|
|
36
|
+
const fetchCustomerOrders: FetchCustomerOrders = async () => {
|
|
37
|
+
state.value.loading = true;
|
|
38
|
+
const { data, error } = await useAsyncData(() =>
|
|
39
|
+
Promise.resolve([
|
|
40
|
+
{ ...order, status: 'Completed' },
|
|
41
|
+
{ ...order, status: 'Shipped' },
|
|
42
|
+
{ ...order, status: 'Open' },
|
|
43
|
+
{ ...order, status: 'Cancelled' },
|
|
44
|
+
] as OrderData[]),
|
|
45
|
+
);
|
|
46
|
+
useHandleError(error.value);
|
|
47
|
+
state.value.data = data.value;
|
|
48
|
+
state.value.loading = false;
|
|
49
|
+
return computed(() => state.value.data) as unknown as Ref<Maybe<OrdersData>>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
fetchCustomerOrders,
|
|
54
|
+
...toRefs(state.value),
|
|
55
|
+
};
|
|
56
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useCustomerReturns } from '~/composables/useCustomerReturns/useCustomerReturns';
|
|
2
|
+
|
|
3
|
+
describe('useCustomerReturns', () => {
|
|
4
|
+
it('should return account data', async () => {
|
|
5
|
+
const { fetchCustomerReturns, data } = useCustomerReturns();
|
|
6
|
+
|
|
7
|
+
await fetchCustomerReturns();
|
|
8
|
+
|
|
9
|
+
expect(data.value).not.toBeUndefined();
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
import { Maybe } from '../_types';
|
|
3
|
+
|
|
4
|
+
export interface UseCustomerReturnsState {
|
|
5
|
+
data: Maybe<unknown[]>;
|
|
6
|
+
loading: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type FetchCustomerReturns = () => Promise<Ref<unknown[] | null>>;
|
|
10
|
+
|
|
11
|
+
export interface UseCustomerReturns {
|
|
12
|
+
data: Readonly<Ref<UseCustomerReturnsState['data']>>;
|
|
13
|
+
loading: Readonly<Ref<boolean>>;
|
|
14
|
+
fetchCustomerReturns: FetchCustomerReturns;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type UseCustomerReturnsReturn = () => UseCustomerReturns;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { toRefs } from '@vueuse/shared';
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import type { Ref } from 'vue';
|
|
4
|
+
import type {
|
|
5
|
+
UseCustomerReturnsReturn,
|
|
6
|
+
UseCustomerReturnsState,
|
|
7
|
+
FetchCustomerReturns,
|
|
8
|
+
} from './types';
|
|
9
|
+
import { useAsyncData, useState } from 'nuxt/app';
|
|
10
|
+
import { useHandleError } from '../useHandleError';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @description Composable managing returns data
|
|
14
|
+
* @returns {@link UseCustomerReturnsReturn}
|
|
15
|
+
* @example
|
|
16
|
+
* const { data, loading, fetchCustomerReturns } = useCustomerReturns();
|
|
17
|
+
*/
|
|
18
|
+
export const useCustomerReturns: UseCustomerReturnsReturn = () => {
|
|
19
|
+
const state = useState<UseCustomerReturnsState>(`useCustomerReturns`, () => ({
|
|
20
|
+
data: [],
|
|
21
|
+
loading: false,
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
/** Function for fetching returns data
|
|
25
|
+
* @example
|
|
26
|
+
* fetchCustomerReturns();
|
|
27
|
+
*/
|
|
28
|
+
const fetchCustomerReturns: FetchCustomerReturns = async () => {
|
|
29
|
+
state.value.loading = true;
|
|
30
|
+
const { data, error } = await useAsyncData(() => Promise.resolve([]));
|
|
31
|
+
useHandleError(error.value);
|
|
32
|
+
state.value.data = data.value;
|
|
33
|
+
state.value.loading = false;
|
|
34
|
+
return computed(() => state.value.data) as unknown as Ref<unknown[] | null>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
fetchCustomerReturns,
|
|
39
|
+
...toRefs(state.value),
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useHandleError';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { UseHandleError, ErrorParams } from './types';
|
|
2
|
+
import { createError } from 'h3';
|
|
3
|
+
|
|
4
|
+
const defaultError: ErrorParams = {
|
|
5
|
+
status: 500,
|
|
6
|
+
message: 'An error occurred',
|
|
7
|
+
statusMessage: 'An error occurred',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @description Composable for handling errors.
|
|
12
|
+
* @param error {@link ErrorParams}
|
|
13
|
+
* @returns Throws an error if there is one.
|
|
14
|
+
* @example
|
|
15
|
+
* const { data, error } = await fetch(data);
|
|
16
|
+
* useHandleError(error.value);
|
|
17
|
+
*/
|
|
18
|
+
export const useHandleError: UseHandleError = (error) => {
|
|
19
|
+
if (error) {
|
|
20
|
+
throw createError({
|
|
21
|
+
statusCode: error.status || defaultError.status,
|
|
22
|
+
message: error.message ?? defaultError.message,
|
|
23
|
+
statusMessage: error.message ?? defaultError.statusMessage,
|
|
24
|
+
fatal: true,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getCommerceClient } from '../utils/client'
|
|
2
|
+
|
|
3
|
+
export function useInventory() {
|
|
4
|
+
const client = getCommerceClient()
|
|
5
|
+
|
|
6
|
+
async function checkInventory(sku: string, qty: number) {
|
|
7
|
+
try {
|
|
8
|
+
// Prefer adapter-provided inventory check when available
|
|
9
|
+
if (client && typeof client.checkInventory === 'function') {
|
|
10
|
+
return await client.checkInventory(sku, qty)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Fallback to Magento inventory endpoint
|
|
14
|
+
const url = `${process.env.COMMERCE_API_URL}${encodeURIComponent(sku)}`
|
|
15
|
+
const res = await fetch(url)
|
|
16
|
+
if (!res.ok) return false
|
|
17
|
+
const data = await res.json()
|
|
18
|
+
const available = (data?.available ?? data?.qty ?? 0) as number
|
|
19
|
+
return available >= qty
|
|
20
|
+
} catch (e) {
|
|
21
|
+
console.error('Inventory check failed', e)
|
|
22
|
+
return false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return { checkInventory }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default useInventory
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
export function useLoading() {
|
|
4
|
+
const active = ref<Record<string, boolean>>({})
|
|
5
|
+
|
|
6
|
+
function startLoading(key = 'default') {
|
|
7
|
+
active.value[key] = true
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function stopLoading(key = 'default') {
|
|
11
|
+
delete active.value[key]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isLoading(key = 'default') {
|
|
15
|
+
return Boolean(active.value[key])
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return { startLoading, stopLoading, isLoading, active }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default useLoading
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
export type NotificationPayload = { type: 'success'|'error'|'info'|'warning'; message: string }
|
|
4
|
+
|
|
5
|
+
const notifications = ref<NotificationPayload[]>([])
|
|
6
|
+
|
|
7
|
+
export function useNotification() {
|
|
8
|
+
function show(payload: NotificationPayload) {
|
|
9
|
+
notifications.value.push(payload)
|
|
10
|
+
// For production-grade UX integrate with a toast library here.
|
|
11
|
+
// Using console as fallback to keep runtime deterministic.
|
|
12
|
+
if (payload.type === 'error') console.error(payload.message)
|
|
13
|
+
else console.log(payload.type.toUpperCase(), payload.message)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function clear() { notifications.value = [] }
|
|
17
|
+
|
|
18
|
+
return { notifications, show, clear }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default useNotification
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useAppConfig } from "nuxt/app";
|
|
2
|
+
|
|
3
|
+
// Avoid relying on ambient auto-imports for `useHead` during typechecking
|
|
4
|
+
const _useHead = (globalThis as any).useHead as ((h: any) => void) | undefined
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Composable for setting the page title.
|
|
9
|
+
* Used in layouts. Title can be changed in pages through the `useHead` composable.
|
|
10
|
+
*/
|
|
11
|
+
export const usePageTitle = () => {
|
|
12
|
+
const { titleSuffix } = useAppConfig();
|
|
13
|
+
|
|
14
|
+
const runner = _useHead || ((globalThis as any).useHead)
|
|
15
|
+
if (typeof runner === 'function') {
|
|
16
|
+
runner({
|
|
17
|
+
titleTemplate: (titleChunk: any) => titleChunk ? `${titleChunk} | ${titleSuffix}` : titleSuffix
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
import type { SfProduct, Maybe } from '../_types';
|
|
3
|
+
|
|
4
|
+
export interface UseProductState {
|
|
5
|
+
data: Maybe<SfProduct>;
|
|
6
|
+
loading: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type FetchProduct = (slug: string) => Promise<Ref<Maybe<SfProduct>>>;
|
|
10
|
+
|
|
11
|
+
export interface UseProduct {
|
|
12
|
+
data: Readonly<Ref<UseProductState['data']>>;
|
|
13
|
+
loading: Readonly<Ref<boolean>>;
|
|
14
|
+
fetchProduct: FetchProduct;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type UseProductReturn = (slug: string) => UseProduct;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { toRefs } from '@vueuse/shared';
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import type { Ref } from 'vue';
|
|
4
|
+
import type { Maybe, Product } from '../_types';
|
|
5
|
+
import type { UseProductReturn, UseProductState, FetchProduct } from './types';
|
|
6
|
+
import { getCommerceClient } from '../../utils/client';
|
|
7
|
+
import { useAsyncData, useState } from 'nuxt/app';
|
|
8
|
+
import { useHandleError } from '../useHandleError';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @description Composable managing product data
|
|
12
|
+
* @param {string} slug Product slug
|
|
13
|
+
* @returns {@link UseProductReturn}
|
|
14
|
+
* @example
|
|
15
|
+
* const { data, loading, fetchProduct } = useProduct('product-slug');
|
|
16
|
+
*/
|
|
17
|
+
export const useProduct: UseProductReturn = (slug) => {
|
|
18
|
+
const state = useState<UseProductState>(`useProduct-${slug}`, () => ({
|
|
19
|
+
data: null,
|
|
20
|
+
loading: false,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
/** Function for fetching product data
|
|
24
|
+
* @param {string} slug Product slug
|
|
25
|
+
* @example
|
|
26
|
+
* fetchProduct('product-slug');
|
|
27
|
+
*/
|
|
28
|
+
const fetchProduct: FetchProduct = async (slug: string) => {
|
|
29
|
+
state.value.loading = true;
|
|
30
|
+
const client = getCommerceClient();
|
|
31
|
+
const { data, error } = await useAsyncData(() => client.getProduct?.(slug) ?? client.fetchProduct?.(slug));
|
|
32
|
+
useHandleError(error.value);
|
|
33
|
+
state.value.data = data.value as unknown as Maybe<Product>;
|
|
34
|
+
state.value.loading = false;
|
|
35
|
+
return computed(() => state.value.data) as unknown as Ref<Maybe<Product>>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
fetchProduct,
|
|
40
|
+
...toRefs(state.value),
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SfProduct } from '../../_types';
|
|
2
|
+
|
|
3
|
+
export const mockProduct: SfProduct = {
|
|
4
|
+
id: '1',
|
|
5
|
+
sku: 'product-1',
|
|
6
|
+
name: 'Product 1',
|
|
7
|
+
slug: 'product-1',
|
|
8
|
+
description: '',
|
|
9
|
+
rating: {
|
|
10
|
+
average: 4.5,
|
|
11
|
+
count: 133,
|
|
12
|
+
},
|
|
13
|
+
price: {
|
|
14
|
+
isDiscounted: false,
|
|
15
|
+
regularPrice: {
|
|
16
|
+
currency: 'USD',
|
|
17
|
+
amount: 100.0,
|
|
18
|
+
precisionAmount: '2',
|
|
19
|
+
},
|
|
20
|
+
value: {
|
|
21
|
+
currency: 'USD',
|
|
22
|
+
amount: 100.0,
|
|
23
|
+
precisionAmount: '2',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
attributes: [],
|
|
27
|
+
primaryImage: null,
|
|
28
|
+
gallery: [],
|
|
29
|
+
variants: [],
|
|
30
|
+
quantityLimit: 1
|
|
31
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useProductAttribute } from '../useProductAttribute';
|
|
2
|
+
import { mockProduct } from './useProduct.mock';
|
|
3
|
+
|
|
4
|
+
describe('useProductAttribute', () => {
|
|
5
|
+
it('should return product attributes', () => {
|
|
6
|
+
const { getAttributeList, getAttribute } = useProductAttribute(mockProduct, ['attribute']);
|
|
7
|
+
|
|
8
|
+
const attributeList = getAttributeList('attribute');
|
|
9
|
+
const attributeValue = getAttribute('attribute');
|
|
10
|
+
|
|
11
|
+
expect(attributeList).toEqual([]);
|
|
12
|
+
expect(attributeValue).toEqual(null);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useProductAttribute';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ref } from 'vue';
|
|
2
|
+
import { SfAttribute, SfProduct } from '../_types';
|
|
3
|
+
import { groupBy, uniqBy } from 'lodash-es';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* composable for getting product attributes data
|
|
7
|
+
* @param {SfProduct} product Product object
|
|
8
|
+
* @param {TAttribute} attributesNames get specific product attributes
|
|
9
|
+
*/
|
|
10
|
+
export function useProductAttribute<TAttribute extends string>(product: SfProduct, attributesNames: TAttribute[] = []) {
|
|
11
|
+
const attributes = groupBy(
|
|
12
|
+
uniqBy(
|
|
13
|
+
(product?.variants || []).flatMap((variant: any) => variant?.attributes),
|
|
14
|
+
'value',
|
|
15
|
+
),
|
|
16
|
+
'name',
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const mapAttribute = (attributes: SfAttribute[] = []) => {
|
|
20
|
+
const defaults = attributesNames.map((attribute) => ({ name: attribute, value: null }));
|
|
21
|
+
|
|
22
|
+
return Object.fromEntries([...defaults, ...attributes].map(({ name, value }) => [name, value]));
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const selectedAttrs = ref(mapAttribute(product.attributes));
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
getAttributeList: (attributeName: TAttribute) => attributes[attributeName] || [],
|
|
29
|
+
getAttribute: (attributeName: TAttribute) => selectedAttrs.value[attributeName],
|
|
30
|
+
setAttribute: (attributeName: TAttribute, attributeValue: string) => {
|
|
31
|
+
selectedAttrs.value = {
|
|
32
|
+
...selectedAttrs.value,
|
|
33
|
+
[attributeName]: attributeValue,
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useProductRecommended } from '~/composables/useProductRecommended/useProductRecommended';
|
|
2
|
+
|
|
3
|
+
describe('useProductRecommended', () => {
|
|
4
|
+
it('should return product reviews', async () => {
|
|
5
|
+
const slug = 'athletic-mens-walking-sneakers';
|
|
6
|
+
const { data: recommendedProducts, fetchProductRecommended } = useProductRecommended(slug);
|
|
7
|
+
|
|
8
|
+
await fetchProductRecommended(slug);
|
|
9
|
+
|
|
10
|
+
expect(recommendedProducts.value).not.toBeUndefined();
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useProductRecommended';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
import type { SfProduct, Maybe } from '../_types';
|
|
3
|
+
|
|
4
|
+
export interface UseProductRecommendedState {
|
|
5
|
+
data: Maybe<SfProduct[]>;
|
|
6
|
+
loading: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type FetchProductRecommended = (slug: string) => Promise<Ref<Maybe<SfProduct[]>>>;
|
|
10
|
+
|
|
11
|
+
export interface UseProductRecommended {
|
|
12
|
+
data: Readonly<Ref<UseProductRecommendedState['data']>>;
|
|
13
|
+
loading: Readonly<Ref<boolean>>;
|
|
14
|
+
fetchProductRecommended: FetchProductRecommended;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type UseProductRecommendedReturn = (slug: string) => UseProductRecommended;
|