From f9ac5af4378b3dba76c786904aaaf11ec16eac2b Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Thu, 2 Jun 2022 11:06:59 +0200 Subject: [PATCH] fix: m2-717. total price and discount calculation --- packages/theme/components/AppHeader.vue | 22 ++++--- packages/theme/components/CartSidebar.vue | 42 +++++++++++--- .../theme/components/Checkout/CartPreview.vue | 12 ++-- .../components/Header/SearchBar/SearchBar.vue | 58 ++++++++++--------- .../Header/SearchBar/SearchResults.vue | 57 +++++++++++++----- .../commands/loadCustomerReviewsCommand.ts | 2 +- packages/theme/getters/types.d.ts | 9 +-- .../modules/checkout/getters/cartGetters.ts | 3 + 8 files changed, 129 insertions(+), 76 deletions(-) diff --git a/packages/theme/components/AppHeader.vue b/packages/theme/components/AppHeader.vue index 046bec65e..d1614a163 100644 --- a/packages/theme/components/AppHeader.vue +++ b/packages/theme/components/AppHeader.vue @@ -86,16 +86,15 @@ @@ -116,16 +115,16 @@ import { useFetch, } from '@nuxtjs/composition-api'; import HeaderNavigation from '~/components/Header/Navigation/HeaderNavigation.vue'; -import { useCategory } from '~/modules/catalog/category/composables/useCategory'; +import useCategory from '~/modules/catalog/category/composables/useCategory'; import { useUiHelpers, useUiState, } from '~/composables'; -import { useCart } from '~/modules/checkout/composables/useCart'; -import { useWishlist } from '~/modules/wishlist/composables/useWishlist'; +import useCart from '~/modules/checkout/composables/useCart'; +import useWishlist from '~/modules/wishlist/composables/useWishlist'; import { useUser } from '~/modules/customer/composables/useUser'; import { useWishlistStore } from '~/modules/wishlist/store/wishlistStore'; -import type { CategoryTree, ProductInterface } from '~/modules/GraphQL/types'; +import type { CategoryTree } from '~/modules/GraphQL/types'; import CurrencySelector from '~/components/CurrencySelector.vue'; import HeaderLogo from '~/components/HeaderLogo.vue'; import SvgImage from '~/components/General/SvgImage.vue'; @@ -157,10 +156,9 @@ export default defineComponent({ const { loadItemsCount: loadWishlistItemsCount } = useWishlist(); const { categories: categoryList, load: categoriesListLoad } = useCategory(); - const isSearchOpen = ref(false); - const productSearchResults = ref(null); - const wishlistStore = useWishlistStore(); + const isSearchOpen = ref(false); + const result = ref(null); const wishlistItemsQty = computed(() => wishlistStore.wishlist?.items_count ?? 0); const wishlistHasProducts = computed(() => wishlistItemsQty.value > 0); @@ -198,7 +196,7 @@ export default defineComponent({ handleAccountClick, isAuthenticated, isSearchOpen, - productSearchResults, + result, setTermForUrl, toggleCartSidebar, toggleWishlistSidebar, diff --git a/packages/theme/components/CartSidebar.vue b/packages/theme/components/CartSidebar.vue index 7dbc88ead..8cfbae88c 100644 --- a/packages/theme/components/CartSidebar.vue +++ b/packages/theme/components/CartSidebar.vue @@ -202,15 +202,37 @@
+ + + + +
+ + @@ -322,6 +344,7 @@ export default defineComponent({ }, }))); const totals = computed(() => cartGetters.getTotals(cart.value)); + const discount = computed(() => -cartGetters.getDiscountAmount(cart.value)); const totalItems = computed(() => cartGetters.getTotalItems(cart.value)); const getAttributes = (product: ConfigurableCartItem) => product.configurable_options || []; const getBundles = (product: BundleCartItem) => product.bundle_options?.map((b) => b.values).flat() || []; @@ -393,6 +416,7 @@ export default defineComponent({ isInStock, imageSizes, getMagentoImage, + discount, }; }, }); @@ -451,10 +475,14 @@ export default defineComponent({ margin: 0; } + &__subtotal, &__discount { + --price-font-weight: var(--font-weight--light); + } + &__total-price { - --price-font-size: var(--font-size--xl); + --price-font-size: var(--font-size--lg); --price-font-weight: var(--font-weight--medium); - margin: 0 0 var(--spacer-base) 0; + margin: var(--spacer-base) 0 var(--spacer-base) 0; } } diff --git a/packages/theme/components/Checkout/CartPreview.vue b/packages/theme/components/Checkout/CartPreview.vue index a09fde007..3cf375e7d 100644 --- a/packages/theme/components/Checkout/CartPreview.vue +++ b/packages/theme/components/Checkout/CartPreview.vue @@ -21,7 +21,7 @@ cartGetters.getItems(cart.value)); const totalItems = computed(() => cartGetters.getTotalItems(cart.value)); const totals = computed(() => cartGetters.getTotals(cart.value)); - const discounts = computed(() => cartGetters.getDiscounts(cart.value)); - const hasDiscounts = computed(() => discounts.value.length > 0); - const discountsAmount = computed( - () => -1 * discounts.value.reduce((a, el) => el.value + a, 0), - ); + const discount = computed(() => -cartGetters.getDiscountAmount(cart.value)); + const hasDiscounts = computed(() => Math.abs(discount.value) > 0); const selectedShippingMethod = computed(() => cartGetters.getSelectedShippingMethod(cart.value)); return { cart, - discounts, - discountsAmount, + discount, hasDiscounts, totalItems, listIsHidden, diff --git a/packages/theme/components/Header/SearchBar/SearchBar.vue b/packages/theme/components/Header/SearchBar/SearchBar.vue index efb3b0603..17d8e7b4d 100644 --- a/packages/theme/components/Header/SearchBar/SearchBar.vue +++ b/packages/theme/components/Header/SearchBar/SearchBar.vue @@ -56,8 +56,7 @@ import { import debounce from 'lodash.debounce'; import { clickOutside } from '~/utilities/directives/click-outside/click-outside-directive'; import SvgImage from '~/components/General/SvgImage.vue'; -import { useProduct } from '~/modules/catalog/product/composables/useProduct'; -import { Products } from '~/modules/GraphQL/types'; +import { useFacet } from '~/modules/catalog/category/composables/useFacet'; export default defineComponent({ name: 'SearchBar', @@ -68,10 +67,6 @@ export default defineComponent({ }, directives: { clickOutside }, props: { - isSearchOpen: { - type: Boolean, - default: false, - }, itemsPerPage: { type: Number, default: 12, @@ -81,16 +76,22 @@ export default defineComponent({ default: 3, }, }, - emits: ['set-is-open', 'set-search-results'], - setup(props, { emit }) { + setup({ itemsPerPage, minTermLen }, { emit }) { const term = ref(''); + const isSearchOpen = ref(false); + const result = ref(null); + const route = useRoute(); - const { getProductList } = useProduct(); + const { + result: searchResult, + search: productsSearch, + } = useFacet(); const showSearch = () => { - if (!props.isSearchOpen) { - emit('set-is-open', true); + if (!isSearchOpen.value) { + isSearchOpen.value = true; + emit('SearchBar:toggle', true); if (document) { document.body.classList.add('no-scroll'); } @@ -98,9 +99,10 @@ export default defineComponent({ }; const hideSearch = () => { - if (props.isSearchOpen) { - emit('set-is-open', false); - emit('set-search-results', null); + if (isSearchOpen.value) { + isSearchOpen.value = false; + emit('SearchBar:toggle', false); + emit('SearchBar:result', {}); if (document) { document.body.classList.remove('no-scroll'); } @@ -108,7 +110,7 @@ export default defineComponent({ }; const toggleSearch = () => { - if (props.isSearchOpen) { + if (isSearchOpen.value) { hideSearch(); } else { showSearch(); @@ -117,10 +119,10 @@ export default defineComponent({ const closeSearch = (event: MouseEvent) => { if (document) { - const searchResultsEl = document.querySelector('.search'); + const searchResultsEl = document.querySelectorAll('.search'); const closeTriggerElement = event.target as HTMLElement; - if (!searchResultsEl?.contains(closeTriggerElement)) { + if (!searchResultsEl[0]?.contains(closeTriggerElement)) { hideSearch(); term.value = ''; } @@ -130,17 +132,20 @@ export default defineComponent({ } }; - const handleSearch = debounce(async (searchTerm: string) => { - term.value = searchTerm; - if (term.value.length < props.minTermLen) return; + const handleSearch = debounce(async (paramValue) => { + term.value = !paramValue.target ? paramValue : paramValue.target.value; + if (term.value.length < minTermLen) return; + + await productsSearch({ + itemsPerPage, + term: term.value, + }); - // M2-579 - const productList : Products = await getProductList({ - pageSize: props.itemsPerPage, - search: term.value, - }) as unknown as Products; + result.value = { + products: searchResult.value?.data?.items, + }; - emit('set-search-results', productList!.items); + emit('SearchBar:result', result.value); }, 1000); watch(route, () => { @@ -154,6 +159,7 @@ export default defineComponent({ hideSearch, toggleSearch, handleSearch, + isSearchOpen, term, }; }, diff --git a/packages/theme/components/Header/SearchBar/SearchResults.vue b/packages/theme/components/Header/SearchBar/SearchResults.vue index c2294582f..43ff5742e 100644 --- a/packages/theme/components/Header/SearchBar/SearchResults.vue +++ b/packages/theme/components/Header/SearchBar/SearchResults.vue @@ -1,7 +1,7 @@