Skip to content

Commit

Permalink
fix: wishlist sidebar (#918)
Browse files Browse the repository at this point in the history
- fix issue with refreshig sidebar wishlist
- fix issue with wishlist sidebar transition
- fix issue with cart sidebar transition
M2-539
  • Loading branch information
bartoszherba authored Apr 25, 2022
1 parent 089c312 commit 51e1b2a
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 73 deletions.
16 changes: 6 additions & 10 deletions packages/theme/components/AppHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ import CurrencySelector from '~/components/CurrencySelector.vue';
import HeaderLogo from '~/components/HeaderLogo.vue';
import SvgImage from '~/components/General/SvgImage.vue';
import StoreSwitcher from '~/components/StoreSwitcher.vue';
import { useCustomerStore } from '~/stores/customer';
export default defineComponent({
components: {
Expand All @@ -161,12 +162,12 @@ export default defineComponent({
const { isAuthenticated } = useUser();
const { loadTotalQty: loadCartTotalQty, cart } = useCart();
const { loadItemsCount: loadWishlistItemsCount } = useWishlist();
const { categories: categoryList, load: categoriesListLoad } = useCategory();
const customerStore = useCustomerStore();
const isSearchOpen = ref(false);
const result = ref(null);
const wishlistItemsQty = ref(null);
const wishlistItemsQty = computed(() => customerStore.wishlist?.items_count ?? 0);
const wishlistHasProducts = computed(() => wishlistItemsQty.value > 0);
const accountIcon = computed(() => (isAuthenticated.value ? 'profile_fill' : 'profile'));
Expand All @@ -187,16 +188,11 @@ export default defineComponent({
.filter((category) => category.include_in_menu);
});
onMounted(() => {
onMounted(async () => {
if (app.$device.isDesktop) {
loadCartTotalQty();
await loadCartTotalQty();
// eslint-disable-next-line promise/catch-or-return
loadWishlistItemsCount({})
.then((response) => {
wishlistItemsQty.value = response;
return response;
});
await loadWishlistItemsCount({});
}
});
Expand Down
1 change: 1 addition & 0 deletions packages/theme/components/CartSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
v-e2e="'sidebar-cart'"
:visible="isCartSidebarOpen"
:title="$t('My Cart')"
position="right"
class="sf-sidebar--right"
@close="toggleCartSidebar"
>
Expand Down
122 changes: 69 additions & 53 deletions packages/theme/components/WishlistSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<SfSidebar
:visible="isWishlistSidebarOpen"
:button="false"
position="right"
title="My Wishlist"
class="sidebar sf-sidebar--right"
@close="toggleWishlistSidebar"
Expand Down Expand Up @@ -40,30 +41,25 @@
</div>
<div class="collected-product-list">
<SfCollectedProduct
v-for="(product, item) in products"
:key="item"
:image="wishlistGetters.getItemImage(product)"
:title="wishlistGetters.getItemName(product)"
v-for="(wishlistItem, itemKey) in wishlistItems"
:key="itemKey"
:image="wishlistItem.product.thumbnail.url"
:title="wishlistItem.product.name"
:regular-price="
$fc(wishlistGetters.getItemPrice(product).regular)
$fc(getItemPrice(wishlistItem).regular)
"
:link="
localePath(
`/p/${wishlistGetters.getItemSku(
product
)}${productGetters.getSlug(
product.product,
product.product.categories[0]
`/p/${wishlistItem.product.sku}${productGetters.getSlug(
wishlistItem.product,
wishlistItem.product.categories[0]
)}`
)
"
:special-price="
wishlistGetters.getItemPrice(product).special &&
$fc(wishlistGetters.getItemPrice(product).special)
"
:special-price="getItemPrice(wishlistItem).special && $fc(getItemPrice(wishlistItem).special)"
:stock="99999"
class="collected-product"
@click:remove="removeItem({ product: product.product })"
@click:remove="removeItem({ product: wishlistItem.product })"
>
<template #input>
<div />
Expand All @@ -72,39 +68,38 @@
<SfLink
:link="
localePath(
`/p/${wishlistGetters.getItemSku(
product
)}${productGetters.getSlug(
product.product,
product.product.categories[0]
`/p/${wishlistItem.product.sku}${productGetters.getSlug(
wishlistItem.product,
wishlistItem.product.categories[0]
)}`
)
"
>
<SfImage
image-tag="nuxt-img"
:src="
getMagentoImage(wishlistGetters.getItemImage(product))
"
:alt="wishlistGetters.getItemName(product)"
:width="140"
:height="200"
:src="getMagentoImage(wishlistItem.product.thumbnail.url)"
:alt="wishlistItem.product.name"
:width="imageSizes.productCard.width"
:height="imageSizes.productCard.height"
:nuxt-img-config="{
fit: 'cover',
}"
class="sf-collected-product__image"
/>
</SfLink>
</template>
<template #configuration>
<div v-if="getAttributes(product).length > 0">
<div v-if="getAttributes(wishlistItem).length > 0">
<SfProperty
v-for="(attr, index) in getAttributes(product)"
v-for="(attr, index) in getAttributes(wishlistItem)"
:key="index"
:name="attr.option_label"
:value="attr.value_label"
/>
</div>
<div v-if="getBundles(product).length > 0">
<div v-if="getBundles(wishlistItem).length > 0">
<SfProperty
v-for="(bundle, i) in getBundles(product)"
v-for="(bundle, i) in getBundles(wishlistItem)"
:key="i"
:value="bundle"
>
Expand All @@ -125,7 +120,7 @@
class="sf-property--full-width my-wishlist__total-price"
>
<template #name>
<span class="my-wishlist__total-price-label">Total price:</span>
<span class="my-wishlist__total-price-label">{{ $t('Total price') }}:</span>
</template>
<template #value>
<SfPrice :regular="$fc(totals.subtotal)" />
Expand Down Expand Up @@ -165,7 +160,7 @@
</SfSidebar>
</div>
</template>
<script>
<script lang="ts">
import {
SfSidebar,
SfHeading,
Expand All @@ -177,12 +172,14 @@ import {
SfLoader,
SfImage,
} from '@storefront-ui/vue';
import { computed, defineComponent, onMounted, ref } from '@nuxtjs/composition-api';
import { wishlistGetters, productGetters } from '~/getters';
import {
useUiState, useImage, useWishlist, useUser,
computed, defineComponent, onMounted,
} from '@nuxtjs/composition-api';
import { productGetters } from '~/getters';
import {
useUiState, useImage, useWishlist, useUser, AgnosticPrice, WishlistItemInterface,
} from '~/composables';
import { useCustomerStore } from '../stores/customer';
import { useCustomerStore } from '~/stores/customer';
import SvgImage from '~/components/General/SvgImage.vue';
export default defineComponent({
Expand All @@ -206,31 +203,50 @@ export default defineComponent({
} = useWishlist();
const { isAuthenticated } = useUser();
const customerStore = useCustomerStore();
const wishlist = ref({});
const products = computed(
() => wishlistGetters.getProducts(wishlist.value) ?? [],
const wishlistItems = computed<WishlistItemInterface[]>(
() => customerStore.wishlist?.items_v2?.items ?? [],
);
const totals = computed(
() => wishlistGetters.getTotals(wishlist.value) ?? {},
const getItemPrice = (product: WishlistItemInterface): AgnosticPrice => {
let regular = 0;
let special = null;
if (product?.product?.price_range) {
regular = product?.product?.price_range.minimum_price.regular_price.value;
const final = product?.product?.price_range.minimum_price.final_price.value;
if (final < regular) {
special = final;
}
}
return {
regular,
special,
};
};
const totals = computed<{ total: number, subtotal: number }>(
() => ((customerStore.wishlist?.items_v2?.items ?? []).length > 0
? customerStore.wishlist?.items_v2?.items.reduce((acc, curr) => ({
total: acc.total + getItemPrice(curr).special,
subtotal: acc.subtotal + getItemPrice(curr).regular,
}), ({ total: 0, subtotal: 0 }))
: ({ total: 0, subtotal: 0 })),
);
const totalItems = computed(
() => wishlistGetters.getTotalItems(wishlist.value) ?? 0,
() => customerStore.wishlist?.items_count ?? 0,
);
const getAttributes = (product) => product?.product?.configurable_options || [];
const getBundles = (product) => product?.product?.items?.map((b) => b.title).flat() || [];
const { getMagentoImage, imageSizes } = useImage();
onMounted(() => {
onMounted(async () => {
if (!customerStore.wishlist.id) {
// eslint-disable-next-line promise/catch-or-return
loadWishlist()
.then((response) => {
wishlist.value = response;
return response;
});
await loadWishlist();
}
});
Expand All @@ -239,17 +255,17 @@ export default defineComponent({
getBundles,
isAuthenticated,
isWishlistSidebarOpen,
products,
wishlistItems,
removeItem,
toggleWishlistSidebar,
totalItems,
totals,
wishlistGetters,
wishlist,
wishlist: customerStore.wishlist,
productGetters,
getMagentoImage,
imageSizes,
loading,
getItemPrice,
};
},
});
Expand Down
10 changes: 3 additions & 7 deletions packages/theme/composables/useWishlist/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function useWishlist(): UseWishlistInterface {
});

// eslint-disable-next-line consistent-return
const load = async (params: UseWishlistLoadParams) => {
const load = async (params?: UseWishlistLoadParams) => {
Logger.debug('useWishlist/load');

try {
Expand All @@ -46,21 +46,17 @@ export function useWishlist(): UseWishlistInterface {
Logger.debug('[Result]:', { data });
const loadedWishlist = data?.customer?.wishlists ?? [];
customerStore.wishlist = loadedWishlist[0] ?? {};

return customerStore.wishlist;
}

customerStore.$patch((state) => {
state.wishlist = null;
});

error.value.load = null;
} catch (err) {
error.value.load = err;
Logger.error('useWishlist/load', err);
} finally {
loading.value = false;
}

return customerStore.wishlist;
};

const isInWishlist = ({ product }: UseWishlistIsInWishlistParams) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/theme/composables/useWishlist/useWishlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export interface UseWishlistInterface {
/**
* Fetches wishlist of the current customer
*/
load(params: UseWishlistLoadParams): Promise<Wishlist | void>; // TODO: Why this method returns a Wishlist but others dont?
load(params?: UseWishlistLoadParams): Promise<Wishlist>;

/**
* Removes product from the wishlist of the current user
Expand All @@ -98,7 +98,7 @@ export interface UseWishlistInterface {
/**
* Indicates whether any of the methods is in progress
*/
loading: DeepReadonly<Ref<boolean>>;
loading: Readonly<Ref<boolean>>;

/**
* Contains errors from any of the composable methods
Expand Down
2 changes: 1 addition & 1 deletion packages/theme/getters/productGetters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ export interface ProductGetters extends ProductGettersBase<Product> {
getProductThumbnailImage(product: Product): string;
getProductUpsellProduct(product: Product): Product[];
getShortDescription(product: Product): string;
getSlug(product: Product, category?: CategoryInterface): string;
getSlug(product: ProductInterface, category?: CategoryInterface): string;
getTypeId(product: Product): string;
getSwatchData(swatchData: Product['configurable_options'][0]['values'][0]['swatch_data']): string | undefined;
getGroupedProducts(product: GroupedProduct): GroupedProduct['items'] | undefined;
Expand Down

0 comments on commit 51e1b2a

Please sign in to comment.