diff --git a/components/Cms/Element/CmsElementImageSlider.vue b/components/Cms/Element/CmsElementImageSlider.vue index b500404f..632e7f9f 100644 --- a/components/Cms/Element/CmsElementImageSlider.vue +++ b/components/Cms/Element/CmsElementImageSlider.vue @@ -8,7 +8,7 @@ const sliderItems = config.getConfigValue('sliderItems'); </script> <template> - <LayoutSlider + <SharedSlider :navigation-arrows="config.getConfigValue('navigationArrows')" :navigation-dots="config.getConfigValue('navigationDots')" :autoplay="config.getConfigValue('autoSlide') ? config.getConfigValue('autoplayTimeout') : false" @@ -18,7 +18,7 @@ const sliderItems = config.getConfigValue('sliderItems'); v-for="(sliderItem, index) in sliderItems" :key="index" > - <LayoutSliderSlide> + <SharedSliderSlide> <template v-if="sliderItem.url"> <NuxtLink :to="sliderItem.url" @@ -47,7 +47,7 @@ const sliderItems = config.getConfigValue('sliderItems'); " loading="lazy" /> - </LayoutSliderSlide> + </SharedSliderSlide> </template> - </LayoutSlider> + </SharedSlider> </template> diff --git a/components/Cms/Element/CmsElementProductListing.vue b/components/Cms/Element/CmsElementProductListing.vue index d805c614..5fc386dc 100644 --- a/components/Cms/Element/CmsElementProductListing.vue +++ b/components/Cms/Element/CmsElementProductListing.vue @@ -66,7 +66,7 @@ const changePage = async (page: number) => { </template> </div> - <LayoutPagination + <UtilityPagination :total="getTotal" :items-per-page="getLimit" :default-page="getCurrentPage" diff --git a/components/Footer/Footer.vue b/components/Footer/Footer.vue new file mode 100644 index 00000000..2921eb1c --- /dev/null +++ b/components/Footer/Footer.vue @@ -0,0 +1,26 @@ +<script setup lang="ts"> +const { navigationElements, loadNavigationElements } = useNavigation({ type: 'footer-navigation' }); +const { navigationElements: serviceNavigationElements, loadNavigationElements: loadServiceElements } = useNavigation({ + type: 'service-navigation', +}); + +onMounted(async () => { + await loadNavigationElements({ depth: 1 }); + await loadServiceElements({ depth: 1 }); +}); +</script> + +<template> + <div class="mt-auto"> + <footer class="mt-4 bg-gray-light md:mt-10"> + <div class="container py-5 md:pb-5 md:pt-10"> + <FooterNavigation :navigation-elements="navigationElements" /> + + <LanguageSwitch /> + + <!-- footer service navigation --> + <FooterServiceNavigation :navigation-elements="serviceNavigationElements" /> + </div> + </footer> + </div> +</template> diff --git a/components/Footer/FooterNavigation.vue b/components/Footer/FooterNavigation.vue new file mode 100644 index 00000000..3ab88619 --- /dev/null +++ b/components/Footer/FooterNavigation.vue @@ -0,0 +1,30 @@ +<script setup lang="ts"> +import type { Schemas } from '@shopware/api-client/api-types'; + +defineProps<{ + navigationElements: Schemas['Category']; +}>(); +</script> + +<template> + <div class="grid gap-5 md:flex md:justify-between lg:justify-normal lg:gap-28"> + <ul + v-for="navigationElement in navigationElements" + :key="navigationElement.id" + class="list-none" + > + <li class="mb-1 max-w-max"> + <NavigationLink + :navigation-element="navigationElement" + classes="font-bold" + /> + </li> + <li + v-for="navigationChild in navigationElement.children" + :key="navigationChild.id" + > + <NavigationLink :navigation-element="navigationChild" /> + </li> + </ul> + </div> +</template> diff --git a/components/Footer/FooterServiceNavigation.vue b/components/Footer/FooterServiceNavigation.vue new file mode 100644 index 00000000..bc2344ac --- /dev/null +++ b/components/Footer/FooterServiceNavigation.vue @@ -0,0 +1,17 @@ +<script setup lang="ts"> +import type { Schemas } from '@shopware/api-client/api-types'; + +defineProps<{ + navigationElements: Schemas['Category']; +}>(); +</script> + +<template> + <div class="mt-4 grid gap-1 border-t-2 border-white pt-4 md:flex md:gap-6"> + <NavigationLink + v-for="navigationElement in navigationElements" + :key="navigationElement.id" + :navigation-element="navigationElement" + /> + </div> +</template> diff --git a/components/FrontendDetailPage.vue b/components/Frontend/FrontendDetailPage.vue similarity index 100% rename from components/FrontendDetailPage.vue rename to components/Frontend/FrontendDetailPage.vue diff --git a/components/FrontendLandingPage.vue b/components/Frontend/FrontendLandingPage.vue similarity index 100% rename from components/FrontendLandingPage.vue rename to components/Frontend/FrontendLandingPage.vue diff --git a/components/FrontendNavigationPage.vue b/components/Frontend/FrontendNavigationPage.vue similarity index 100% rename from components/FrontendNavigationPage.vue rename to components/Frontend/FrontendNavigationPage.vue diff --git a/components/Layout/Header/LayoutHeader.vue b/components/Header/Header.vue similarity index 86% rename from components/Layout/Header/LayoutHeader.vue rename to components/Header/Header.vue index 8423973b..7fd96cb6 100644 --- a/components/Layout/Header/LayoutHeader.vue +++ b/components/Header/Header.vue @@ -14,10 +14,10 @@ const { loading } = storeToRefs(customerStore); <!-- mobile menu --> <NavigationSidebar /> - <LayoutLogo logo-classes="w-36 md:w-40" /> + <UtilityLogo logo-classes="w-36 md:w-40" /> </div> - <LayoutHeaderActions /> + <HeaderActions /> </div> </div> diff --git a/components/Layout/Header/LayoutHeaderAccount.vue b/components/Header/HeaderAccount.vue similarity index 100% rename from components/Layout/Header/LayoutHeaderAccount.vue rename to components/Header/HeaderAccount.vue diff --git a/components/Header/HeaderActions.vue b/components/Header/HeaderActions.vue new file mode 100644 index 00000000..e7a26c9a --- /dev/null +++ b/components/Header/HeaderActions.vue @@ -0,0 +1,11 @@ +<template> + <div class="flex items-center gap-3.5"> + <HeaderSearch /> + + <HeaderWishlist /> + + <HeaderAccount /> + + <HeaderCart /> + </div> +</template> diff --git a/components/Layout/Header/LayoutHeaderCart.vue b/components/Header/HeaderCart.vue similarity index 96% rename from components/Layout/Header/LayoutHeaderCart.vue rename to components/Header/HeaderCart.vue index ec6a3efc..7c26be6e 100644 --- a/components/Layout/Header/LayoutHeaderCart.vue +++ b/components/Header/HeaderCart.vue @@ -21,7 +21,7 @@ const cartItemCount = computed(() => getCartItemsCount(cartItems.value)); /> </button> - <LazyLayoutSidebar + <LazySharedSidebar v-if="offcanvasCartController.isOpen" :controller="offcanvasCartController" side="right" @@ -48,5 +48,5 @@ const cartItemCount = computed(() => getCartItemsCount(cartItems.value)); to the cart </NuxtLink> </template> - </LazyLayoutSidebar> + </LazySharedSidebar> </template> diff --git a/components/Layout/Header/LayoutHeaderWishlist.vue b/components/Header/HeaderWishlist.vue similarity index 100% rename from components/Layout/Header/LayoutHeaderWishlist.vue rename to components/Header/HeaderWishlist.vue diff --git a/components/Layout/Header/Search/LayoutHeaderSearch.vue b/components/Header/Search/HeaderSearch.vue similarity index 95% rename from components/Layout/Header/Search/LayoutHeaderSearch.vue rename to components/Header/Search/HeaderSearch.vue index 898442ec..aba1dab4 100644 --- a/components/Layout/Header/Search/LayoutHeaderSearch.vue +++ b/components/Header/Search/HeaderSearch.vue @@ -23,7 +23,7 @@ onClickOutside(searchComponent, event => { <ClientOnly> <teleport to="#flyouts"> - <LayoutHeaderSearchBar + <HeaderSearchBar v-if="searchVisible" ref="searchComponent" @close-search="searchVisible = false" diff --git a/components/Layout/Header/Search/LayoutHeaderSearchBar.vue b/components/Header/Search/HeaderSearchBar.vue similarity index 98% rename from components/Layout/Header/Search/LayoutHeaderSearchBar.vue rename to components/Header/Search/HeaderSearchBar.vue index 7b9ea122..ebf7bc53 100644 --- a/components/Layout/Header/Search/LayoutHeaderSearchBar.vue +++ b/components/Header/Search/HeaderSearchBar.vue @@ -88,7 +88,7 @@ onMounted(() => { :to="getProductRoute(product)" @click="$emit('closeSearch')" > - <LayoutHeaderSearchSuggestions :product="product" /> + <HeaderSearchSuggestions :product="product" /> </NuxtLink> <div class="bg-gray-light text-center text-sm hover:bg-gray-medium"> diff --git a/components/Layout/Header/Search/LayoutHeaderSearchSuggestions.vue b/components/Header/Search/HeaderSearchSuggestions.vue similarity index 100% rename from components/Layout/Header/Search/LayoutHeaderSearchSuggestions.vue rename to components/Header/Search/HeaderSearchSuggestions.vue diff --git a/components/LanguageSwitch.vue b/components/LanguageSwitch.vue index 931e633e..2e952a2d 100644 --- a/components/LanguageSwitch.vue +++ b/components/LanguageSwitch.vue @@ -19,17 +19,19 @@ const languageOptions = computed(() => entityArrayToOptions<Schemas['language']> </script> <template> - <div - v-if="languages" - class="py-4 md:w-1/5" - > - <FormKit - v-model="languageIdChain" - type="select" - name="language" - prefix-icon="globe" - :options="languageOptions" - @change="onLanguageChange" - /> - </div> + <ClientOnly> + <div + v-if="languages" + class="py-4 md:w-1/5" + > + <FormKit + v-model="languageIdChain" + type="select" + name="language" + prefix-icon="globe" + :options="languageOptions" + @change="onLanguageChange" + /> + </div> + </ClientOnly> </template> diff --git a/components/Layout/Header/LayoutHeaderActions.vue b/components/Layout/Header/LayoutHeaderActions.vue deleted file mode 100644 index 423588fb..00000000 --- a/components/Layout/Header/LayoutHeaderActions.vue +++ /dev/null @@ -1,11 +0,0 @@ -<template> - <div class="flex items-center gap-3.5"> - <LayoutHeaderSearch /> - - <LayoutHeaderWishlist /> - - <LayoutHeaderAccount /> - - <LayoutHeaderCart /> - </div> -</template> diff --git a/components/Layout/LayoutFooter.vue b/components/Layout/LayoutFooter.vue deleted file mode 100644 index 5101ce3d..00000000 --- a/components/Layout/LayoutFooter.vue +++ /dev/null @@ -1,72 +0,0 @@ -<script setup lang="ts"> -import { getTranslatedProperty, getCategoryRoute } from '@shopware-pwa/helpers-next'; - -const { navigationElements, loadNavigationElements } = useNavigation({ type: 'footer-navigation' }); -const { navigationElements: serviceNavigationElements, loadNavigationElements: loadServiceElements } = useNavigation({ - type: 'service-navigation', -}); - -onMounted(async () => { - await loadNavigationElements({ depth: 1 }); - await loadServiceElements({ depth: 1 }); -}); -</script> - -<template> - <div class="mt-auto"> - <footer class="mt-4 bg-gray-light md:mt-10"> - <div class="container py-5 md:pb-5 md:pt-10"> - <!-- footer navigation --> - <div class="grid gap-5 md:flex md:justify-between lg:justify-normal lg:gap-28"> - <template - v-for="navigationElement in navigationElements" - :key="navigationElement.id" - > - <ul class="list-none"> - <li class="mb-1 max-w-max font-bold hover:text-brand-primary hover:underline"> - <NuxtLink - :target=" - navigationElement.externalLink || navigationElement.linkNewTab ? '_blank' : '' - " - :to="getCategoryRoute(navigationElement)" - > - {{ getTranslatedProperty(navigationElement, 'name') }} - </NuxtLink> - </li> - <li - v-for="navigationChild in navigationElement.children" - :key="navigationChild.id" - > - <NuxtLink - :target="navigationChild.externalLink || navigationChild.linkNewTab ? '_blank' : ''" - :to="getCategoryRoute(navigationChild)" - class="text-sm font-normal transition duration-200 hover:text-brand-primary hover:underline" - > - {{ getTranslatedProperty(navigationChild, 'name') }} - </NuxtLink> - </li> - </ul> - </template> - </div> - - <LanguageSwitch /> - - <!-- footer service navigation --> - <div class="mt-4 grid gap-1 border-t-2 border-white pt-4 md:flex md:gap-6"> - <template - v-for="navigationElement in serviceNavigationElements" - :key="navigationElement.id" - > - <NuxtLink - :target="navigationElement.externalLink || navigationElement.linkNewTab ? '_blank' : ''" - :to="getCategoryRoute(navigationElement)" - class="text-sm font-normal transition duration-200 hover:text-brand-primary hover:underline" - > - {{ getTranslatedProperty(navigationElement, 'name') }} - </NuxtLink> - </template> - </div> - </div> - </footer> - </div> -</template> diff --git a/components/Navigation/NavigationFlyout.vue b/components/Navigation/NavigationFlyout.vue index 6caf38c9..8d7edd84 100644 --- a/components/Navigation/NavigationFlyout.vue +++ b/components/Navigation/NavigationFlyout.vue @@ -29,7 +29,6 @@ const selfNotHovered = refDebounced(isOutsideFlyout, 200); :navigation-element="child" classes="text-lg font-bold py-2" active-classes="text-brand-primary" - :as-link="child.type !== 'folder'" /> <div class="flex flex-col gap-2"> <template v-if="child.childCount > 0"> @@ -39,7 +38,6 @@ const selfNotHovered = refDebounced(isOutsideFlyout, 200); :navigation-element="subChild" classes="py-2" active-classes="text-brand-primary" - :as-link="subChild.type !== 'folder'" /> </template> </div> diff --git a/components/Navigation/NavigationLink.vue b/components/Navigation/NavigationLink.vue index 9b3fce6d..db9cfb5e 100644 --- a/components/Navigation/NavigationLink.vue +++ b/components/Navigation/NavigationLink.vue @@ -34,11 +34,13 @@ const isActive = (path: Schemas['SeoUrl'][] | undefined, onlyExactMatch: boolean return onlyExactMatch ? formattedPath === currentPath : currentPath.includes(formattedPath); }; + +const isFolder = computed(() => props.navigationElement.type !== 'folder'); </script> <template> <NuxtLink - v-if="asLink" + v-if="isFolder && asLink" :target="isExternalLink || linkNewTab ? '_blank' : ''" :rel="isExternalLink || linkNewTab ? 'noopener noreferrer nofollow' : ''" :aria-label="getTranslatedProperty(navigationElement, 'name')" diff --git a/components/Navigation/NavigationMainItem.vue b/components/Navigation/NavigationMainItem.vue index c57f86bb..893d434c 100644 --- a/components/Navigation/NavigationMainItem.vue +++ b/components/Navigation/NavigationMainItem.vue @@ -23,11 +23,10 @@ const debounced = refDebounced(isOutsideNavItem, 300); :class="{ 'text-brand-primary': !debounced, }" - :as-link="navigationElement.type !== 'folder'" /> </div> - <NavigationFlyout + <LazyNavigationFlyout v-if="navigationElement?.childCount > 0" :navigation-element="navigationElement" :parent-hovered="!debounced" diff --git a/components/Navigation/NavigationSidebar.vue b/components/Navigation/NavigationSidebar.vue index 763bb915..0bf42d22 100644 --- a/components/Navigation/NavigationSidebar.vue +++ b/components/Navigation/NavigationSidebar.vue @@ -47,7 +47,7 @@ const lastPreviousItem = computed(() => class="w-4 cursor-pointer md:hidden" @click="sideMenuController.open()" /> - <LazyLayoutSidebar + <LazySharedSidebar v-if="sideMenuController.isOpen" :controller="sideMenuController" > @@ -88,5 +88,5 @@ const lastPreviousItem = computed(() => /> </div> </template> - </LazyLayoutSidebar> + </LazySharedSidebar> </template> diff --git a/components/Utility/UtilityToastNotifications.vue b/components/Notification/NotificationContainer.vue similarity index 91% rename from components/Utility/UtilityToastNotifications.vue rename to components/Notification/NotificationContainer.vue index 8d8dd6dd..9e420920 100644 --- a/components/Utility/UtilityToastNotifications.vue +++ b/components/Notification/NotificationContainer.vue @@ -4,7 +4,7 @@ const { notifications } = useNotifications(); <template> <div class="fixed bottom-10 right-5 z-[2147483647] flex max-h-fit w-96 max-w-[calc(100vw-2.5rem)] flex-col gap-2.5"> - <UtilityToastNotification + <NotificationToast v-for="notification in notifications" :key="notification.id" :notification="notification" diff --git a/components/Utility/UtilityStaticNotification.vue b/components/Notification/NotificationStatic.vue similarity index 83% rename from components/Utility/UtilityStaticNotification.vue rename to components/Notification/NotificationStatic.vue index 9c65d16e..680b00e2 100644 --- a/components/Utility/UtilityStaticNotification.vue +++ b/components/Notification/NotificationStatic.vue @@ -16,5 +16,5 @@ const staticNotification: Notification = { </script> <template> - <UtilityToastNotification :notification="staticNotification" /> + <NotificationToast :notification="staticNotification" /> </template> diff --git a/components/Utility/UtilityToastNotification.vue b/components/Notification/NotificationToast.vue similarity index 100% rename from components/Utility/UtilityToastNotification.vue rename to components/Notification/NotificationToast.vue diff --git a/components/Product/ProductAvailability.vue b/components/Product/ProductAvailability.vue index 05318f82..91984e3f 100644 --- a/components/Product/ProductAvailability.vue +++ b/components/Product/ProductAvailability.vue @@ -7,8 +7,8 @@ const props = defineProps<{ const availableStock = props.product.availableStock ?? props.product.deliveryInformation.stock ?? 0; const minPurchase = props.product.minPurchase ?? props.product.quantityInformation.minPurchase ?? 0; -const deliveryTime = props.product.deliveryTime ?? props.product.deliveryInformation.deliveryTime; -const restockTime = props.product.restockTime ?? props.product.deliveryInformation.restockTime; +const deliveryTime = props.product?.deliveryTime ?? props.product.deliveryInformation?.deliveryTime; +const restockTime = props.product?.restockTime ?? props.product.deliveryInformation?.restockTime; </script> <template> diff --git a/components/Layout/LayoutSidebar.vue b/components/Shared/SharedSidebar.vue similarity index 100% rename from components/Layout/LayoutSidebar.vue rename to components/Shared/SharedSidebar.vue diff --git a/components/Layout/Slider/LayoutSliderSlide.vue b/components/Shared/Slider/ShardSliderSlide.vue similarity index 100% rename from components/Layout/Slider/LayoutSliderSlide.vue rename to components/Shared/Slider/ShardSliderSlide.vue diff --git a/components/Layout/Slider/LayoutSlider.vue b/components/Shared/Slider/SharedSlider.vue similarity index 100% rename from components/Layout/Slider/LayoutSlider.vue rename to components/Shared/Slider/SharedSlider.vue diff --git a/components/Layout/LayoutBreadcrumbs.vue b/components/Utility/UtilityBreadcrumbs.vue similarity index 100% rename from components/Layout/LayoutBreadcrumbs.vue rename to components/Utility/UtilityBreadcrumbs.vue diff --git a/components/Layout/LayoutLogo.vue b/components/Utility/UtilityLogo.vue similarity index 100% rename from components/Layout/LayoutLogo.vue rename to components/Utility/UtilityLogo.vue diff --git a/components/Layout/LayoutPagination.vue b/components/Utility/UtilityPagination.vue similarity index 100% rename from components/Layout/LayoutPagination.vue rename to components/Utility/UtilityPagination.vue diff --git a/error.vue b/error.vue index b705faf9..bd4d4ccb 100644 --- a/error.vue +++ b/error.vue @@ -17,9 +17,9 @@ refreshCart(); <NuxtLoadingIndicator /> <UtilityLoadingSpinner v-if="loading" /> - <LayoutHeader v-show="!loading" /> + <Header v-show="!loading" /> - <UtilityToastNotifications /> + <NotificationContainer /> <main v-show="!loading" @@ -37,5 +37,5 @@ refreshCart(); </div> </main> - <LayoutFooter v-show="!loading" /> + <Footer v-show="!loading" /> </template> diff --git a/layouts/default.vue b/layouts/default.vue index 53209045..4ed32377 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -14,20 +14,20 @@ refreshCart(); <NuxtRouteAnnouncer /> <UtilityLoadingSpinner v-if="loading" /> - <LayoutHeader v-show="!loading" /> + <Header v-show="!loading" /> - <UtilityToastNotifications /> + <NotificationContainer /> <main v-show="!loading" class="mt-4 w-screen" > - <LayoutBreadcrumbs /> + <UtilityBreadcrumbs /> <NuxtPage /> </main> - <LayoutFooter v-show="!loading" /> + <Footer v-show="!loading" /> </template> <style> diff --git a/package.json b/package.json index a646dfb5..dcb6573b 100755 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@basecom-gmbh/pond", "type": "module", "main": "./nuxt.config.ts", - "version": "0.0.2", + "version": "0.0.6", "scripts": { "build": "nuxt build", "dev": "nuxt dev", diff --git a/pages/checkout/cart.vue b/pages/checkout/cart.vue index 7a2484c1..36fcca1d 100644 --- a/pages/checkout/cart.vue +++ b/pages/checkout/cart.vue @@ -39,7 +39,7 @@ useBreadcrumbs(checkoutBreadcrumbs({ index: 0 })); </div> <template v-else> - <UtilityStaticNotification + <NotificationStatic id="empty-cart" type="info" message="Your cart is empty."