-
Couldn't load subscription status.
- Fork 38
feat(VCST-4084): saved for later list page #2008
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
5c13a3c
92e3083
e4e1939
668f850
67bbb6b
0788f5e
f91cf32
89e7e44
fba59ce
9d387c0
b5f10dd
ec9da63
75a94a0
3e8a612
4029d72
1345cfd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -101,6 +101,15 @@ | |
| "icon": "clipboard-list", | ||
| "priority": 50 | ||
| }, | ||
| { | ||
| "id": "saved-for-later", | ||
| "route": { | ||
| "name": "SavedForLater" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }, | ||
| "title": "shared.layout.header.mobile.account_menu.saved_for_later", | ||
| "icon": "list-v2", | ||
| "priority": 55 | ||
| }, | ||
| { | ||
| "id": "lists", | ||
| "route": { | ||
|
|
@@ -236,6 +245,14 @@ | |
| "icon": "clipboard-list", | ||
| "priority": 40 | ||
| }, | ||
| { | ||
| "route": { | ||
| "name": "SavedForLater" | ||
| }, | ||
| "title": "shared.layout.header.mobile.account_menu.saved_for_later", | ||
| "icon": "list-v2", | ||
| "priority": 45 | ||
| }, | ||
| { | ||
| "route": { | ||
| "name": "Lists" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,12 +7,12 @@ | |
| <div class="flex flex-col"> | ||
| <!-- Title block --> | ||
| <div class="contents md:flex md:flex-wrap md:items-center md:justify-between md:gap-3"> | ||
| <VcTypography v-if="list?.name" tag="h1" truncate> | ||
| {{ list.name }} | ||
| <VcTypography v-if="actualListName" tag="h1" truncate> | ||
| {{ actualListName }} | ||
| </VcTypography> | ||
|
|
||
| <!-- Title skeleton --> | ||
| <div v-else class="w-2/3 bg-neutral-200 text-3xl md:w-1/3"> </div> | ||
| <div v-else class="w-2/3 bg-neutral-200 text-3xl md:w-1/3">{{ props.listName ?? " " }}</div> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| <div class="order-last mt-8 flex flex-wrap gap-3 md:ms-0 md:mt-0 md:shrink-0 lg:my-0"> | ||
| <VcButton | ||
|
|
@@ -49,6 +49,7 @@ | |
| </VcButton> | ||
|
|
||
| <VcButton | ||
| v-if="!hideSettings" | ||
| :disabled="loading || !list" | ||
| size="sm" | ||
| variant="outline" | ||
|
|
@@ -63,15 +64,7 @@ | |
|
|
||
| <div ref="listElement" class="mt-5 w-full"> | ||
| <!-- Skeletons --> | ||
| <template v-if="listLoading"> | ||
| <div v-if="isMobile" class="grid grid-cols-2 gap-x-4 gap-y-6"> | ||
| <ProductSkeletonGrid v-for="i in actualPageRowsCount" :key="i" /> | ||
| </div> | ||
|
|
||
| <div v-else class="flex flex-col rounded border bg-additional-50 shadow-sm"> | ||
| <WishlistProductItemSkeleton v-for="i in actualPageRowsCount" :key="i" class="even:bg-neutral-50" /> | ||
| </div> | ||
| </template> | ||
| <WishlistProductsSkeleton v-if="listLoading" :itemsCount="actualPageRowsCount" /> | ||
|
|
||
| <!-- List details --> | ||
| <template v-else-if="!listLoading && !!list?.items?.length"> | ||
|
|
@@ -137,7 +130,6 @@ import { prepareLineItem, Logger } from "@/core/utilities"; | |
| import { ROUTES } from "@/router/routes/constants"; | ||
| import { dataChangedEvent, useBroadcast } from "@/shared/broadcast"; | ||
| import { useShortCart, getItemsForAddBulkItemsToCartResultsModal } from "@/shared/cart"; | ||
| import { ProductSkeletonGrid } from "@/shared/catalog"; | ||
| import { SaveChangesModal } from "@/shared/common"; | ||
| import { BackButtonInHeader } from "@/shared/layout"; | ||
| import { useModal } from "@/shared/modal"; | ||
|
|
@@ -146,7 +138,7 @@ import { | |
| AddOrUpdateWishlistModal, | ||
| DeleteWishlistProductModal, | ||
| WishlistLineItems, | ||
| WishlistProductItemSkeleton, | ||
| WishlistProductsSkeleton, | ||
| } from "@/shared/wishlists"; | ||
| import type { | ||
| InputUpdateWishlistItemsType, | ||
|
|
@@ -160,9 +152,13 @@ import AddBulkItemsToCartResultsModal from "@/shared/cart/components/add-bulk-it | |
|
|
||
| interface IProps { | ||
| listId: string; | ||
| hideSettings?: boolean; | ||
| listName?: string; | ||
| } | ||
|
|
||
| const props = defineProps<IProps>(); | ||
| const props = withDefaults(defineProps<IProps>(), { | ||
| listName: undefined, | ||
| }); | ||
|
|
||
| const Error404 = defineAsyncComponent(() => import("@/pages/404.vue")); | ||
|
|
||
|
|
@@ -224,6 +220,8 @@ const wishlistListProperties = computed(() => ({ | |
| related_type: "wishlist", | ||
| })); | ||
|
|
||
| const actualListName = computed(() => props.listName ?? list.value?.name); | ||
|
|
||
| const isMobile = breakpoints.smaller("lg"); | ||
|
|
||
| function openListSettingsModal(): void { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| <template> | ||
| <template v-if="saveForLaterLoading"> | ||
| <div class="contents md:flex md:flex-wrap md:items-center md:justify-between md:gap-3"> | ||
| <VcTypography tag="h1"> | ||
| {{ $t("pages.cart.saved_for_later") }} | ||
| </VcTypography> | ||
| </div> | ||
|
|
||
| <div class="mt-5 w-full"> | ||
| <WishlistProductsSkeleton :itemsCount="6" /> | ||
| </div> | ||
| </template> | ||
|
|
||
| <ListDetails | ||
| v-else-if="savedForLaterListId && !savedForLaterListIsEmpty" | ||
| :list-id="savedForLaterListId" | ||
| :list-name="$t('pages.cart.saved_for_later')" | ||
| hide-settings | ||
| /> | ||
|
|
||
| <div v-else> | ||
| <VcTypography tag="h1"> | ||
| {{ $t("pages.cart.saved_for_later") }} | ||
| </VcTypography> | ||
|
|
||
| <VcEmptyView :text="$t('pages.cart.saved_for_later_not_found')" icon="list-v2" /> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script lang="ts" setup> | ||
| import { computed, onMounted } from "vue"; | ||
| import { useSavedForLater } from "@/shared/cart/composables/useSaveForLater"; | ||
| import { WishlistProductsSkeleton } from "@/shared/wishlists"; | ||
| import ListDetails from "./list-details.vue"; | ||
|
|
||
| const { savedForLaterList, loading: saveForLaterLoading, getSavedForLater } = useSavedForLater(); | ||
|
|
||
| const savedForLaterListId = computed(() => savedForLaterList.value?.id); | ||
| const savedForLaterListIsEmpty = computed(() => !savedForLaterList.value?.items?.length); | ||
|
|
||
| onMounted(() => { | ||
| void getSavedForLater(); | ||
| }); | ||
| </script> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| <template> | ||
| <div v-if="isMobile" class="wishlist-products-skeleton wishlist-products-skeleton--mobile"> | ||
| <ProductSkeletonGrid v-for="i in itemsCount" :key="i" class="wishlist-products-skeleton__item" /> | ||
| </div> | ||
|
|
||
| <div v-else class="wishlist-products-skeleton wishlist-products-skeleton--desktop"> | ||
| <WishlistProductItemSkeleton v-for="i in itemsCount" :key="i" class="wishlist-products-skeleton__item" /> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script lang="ts" setup> | ||
| import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"; | ||
| import { ProductSkeletonGrid } from "@/shared/catalog"; | ||
| import { WishlistProductItemSkeleton } from "@/shared/wishlists"; | ||
|
|
||
| interface IProps { | ||
| itemsCount: number; | ||
| } | ||
|
|
||
| defineProps<IProps>(); | ||
|
|
||
| const breakpoints = useBreakpoints(breakpointsTailwind); | ||
|
|
||
| const isMobile = breakpoints.smaller("lg"); | ||
| </script> | ||
|
|
||
| <style lang="scss"> | ||
| .wishlist-products-skeleton { | ||
| $desktop: ""; | ||
|
|
||
| &--mobile { | ||
| @apply grid grid-cols-2 gap-x-4 gap-y-6; | ||
| } | ||
|
|
||
| &--desktop { | ||
| @apply flex flex-col rounded border bg-additional-50 shadow-sm; | ||
|
|
||
| $desktop: &; | ||
| } | ||
|
|
||
| &__item { | ||
| #{$desktop} & { | ||
| @apply even:bg-neutral-50; | ||
| } | ||
| } | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: CSS Class Naming Violates BEM ConventionThe CSS class naming does not follow the BEM naming convention as specifically requested by the reviewer. The classes should be named based on the component name (e.g., "wishlist-products-skeleton wishlist-products-skeleton--mobile") instead of generic names like "skeleton-mobile" and "skeleton-desktop". This violates the project's naming standards as indicated in the PR discussion. |
||
| </style> | ||
Uh oh!
There was an error while loading. Please reload this page.