build / build (push) Successful in 1m38s
Recovered work in progress that sat uncommitted since 2026-05: a SelectionBox renders as a plain div instead of a NuxtLink when locked, so a variant with only one choice reads as decided rather than clickable, and it reports aria-checked in that state. useProductContent gained the content lookups the details and index pages now use, the cookie banner says Schließen instead of Akzeptieren, the Über uns header entry is gone, and ProductCard's hover shadow no longer relies on a short-circuit that could yield a non-array.
99 lines
3.6 KiB
Vue
99 lines
3.6 KiB
Vue
<template>
|
|
<header class="text-gray-900 z-50" :class="{ 'bg-white bg-opacity-95 absolute shadow-xl top-0 left-0 right-0 z-[99999]': isDarkMode }">
|
|
<div class="xl:container mx-auto lg:text-lg">
|
|
<div class="flex flex-col lg:flex-row lg:gap-12 relative">
|
|
<div class="flex lg:w-1/4 justify-between">
|
|
<NuxtLink to="/" class="max-sm:sticky max-sm:top-0 p-6 py-6 lg:py-7 hover:text-red-600" @click="trackEvent('header-logo-clicked')">
|
|
<span class="tracking-wide text-3xl font-bebas leading-none block">
|
|
<span class="!text-black">MUELLERPRINTS</span>.<br />Paperwork
|
|
</span>
|
|
</NuxtLink>
|
|
|
|
<button @click="toggleMobileMenu()" class="p-6 py-6 lg:py-7 lg:hidden" :class="{ 'bg-white': !isDarkMode }" aria-label="Menü öffnen" :aria-expanded="isMobileMenuOpen">
|
|
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div
|
|
v-if="route.name"
|
|
role="navigation"
|
|
class="grow lg:w-3/4 p-6 py-6 lg:py-7 hidden lg:block bg-transparent"
|
|
:class="{ '!block bg-white': isMobileMenuOpen, 'text-gray-900': isMobileMenuOpen && isDarkMode }"
|
|
>
|
|
<nav class="flex justify-end" v-if="isCheckoutRoute" aria-label="Navigation">
|
|
<HeaderNavLink v-if="!isPaymentRoute" label="Zurück zum Warenkorb" path="/cart" @click="trackEvent('header-back-to-cart-clicked')" />
|
|
</nav>
|
|
<nav
|
|
class="flex flex-col lg:flex-row justify-between gap-4 lg:gap-28 lg:h-full"
|
|
v-else
|
|
aria-label="Navigation"
|
|
@click="closeMobileMenu()"
|
|
>
|
|
<div class="flex flex-col lg:flex-row gap-4 lg:gap-2">
|
|
<HeaderNavLink
|
|
label="Shop"
|
|
description="Alle Notizbücher"
|
|
path="/notebooks"
|
|
@click="trackEvent('header-item-clicked', { label: 'Shop' })"
|
|
/>
|
|
<HeaderNavLink
|
|
v-for="item in sortedCovers"
|
|
:key="item.id"
|
|
:label="item.label"
|
|
:description="item.description"
|
|
:path="`/notebooks/${item.slug}`"
|
|
@click="trackEvent('header-item-clicked', { label: item.label })"
|
|
/>
|
|
</div>
|
|
<NuxtLink
|
|
to="/cart"
|
|
class="px-4 py-0.5 rounded-full font-medium text-lg text-black transition-all duration-200 flex items-center gap-2 hover:bg-gray-900 hover:text-white"
|
|
active-class="!bg-gray-900 !text-white"
|
|
title="Warenkorb"
|
|
@click="trackEvent('header-cart-clicked')"
|
|
>
|
|
Warenkorb
|
|
<span
|
|
v-if="productsCount > 0"
|
|
class="inline-flex items-center justify-center w-5 h-5 text-xs font-semibold rounded-full bg-gray-900 text-white group-hover:bg-white group-hover:text-gray-900"
|
|
:class="{ '!bg-white !text-gray-900': $route.path === '/cart' }"
|
|
>
|
|
{{ productsCount }}
|
|
</span>
|
|
</NuxtLink>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { CoverNavItem } from "~/types";
|
|
|
|
const props = defineProps<{
|
|
covers: CoverNavItem[];
|
|
isDarkMode?: boolean;
|
|
}>();
|
|
|
|
const route = useRoute();
|
|
const { productsCount } = useCart();
|
|
|
|
const isMobileMenuOpen = ref(false);
|
|
|
|
const sortedCovers = computed(() => [...props.covers].sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0)));
|
|
|
|
const isCheckoutRoute = computed(() => String(route.name).startsWith("checkout-"));
|
|
|
|
const isPaymentRoute = computed(() => route.name === "checkout-3");
|
|
|
|
function toggleMobileMenu() {
|
|
isMobileMenuOpen.value = !isMobileMenuOpen.value;
|
|
}
|
|
|
|
function closeMobileMenu() {
|
|
isMobileMenuOpen.value = false;
|
|
}
|
|
</script>
|