feat(nav): client area tabs in main navigation
Some checks failed
Build Docker Image / build (push) Has been cancelled
Some checks failed
Build Docker Image / build (push) Has been cancelled
- Add Cabinet button to header (dashboard icon) - When in /clientarea/* show tabs instead of search input - Tabs: Заказы | Предложения (SELLER only) | Адреса | Профиль | Команда - Hide Explore/Quote toggle in client area - Remove SubNavigation for clientarea (tabs moved to MainNavigation)
This commit is contained in:
@@ -12,8 +12,8 @@
|
||||
<span class="font-bold text-xl" :class="useWhiteText ? 'text-white' : 'text-base-content'">Optovia</span>
|
||||
</NuxtLink>
|
||||
|
||||
<!-- Service nav links -->
|
||||
<nav v-if="showModeToggle" class="flex items-center gap-1">
|
||||
<!-- Service nav links (hide in client area) -->
|
||||
<nav v-if="showModeToggle && !isClientArea" class="flex items-center gap-1">
|
||||
<button
|
||||
class="px-3 py-1 text-sm font-medium rounded-lg transition-colors"
|
||||
:class="showActiveMode && catalogMode === 'explore'
|
||||
@@ -35,13 +35,55 @@
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Center: Search input (vertically centered) -->
|
||||
<!-- Center: Search input OR Client Area tabs (vertically centered) -->
|
||||
<div class="flex-1 flex flex-col items-center max-w-2xl mx-auto gap-2 justify-center">
|
||||
<!-- Hero slot for home page title -->
|
||||
<slot name="hero" />
|
||||
|
||||
<!-- Client Area tabs -->
|
||||
<template v-if="isClientArea">
|
||||
<div class="flex items-center gap-1 rounded-full border border-white/20 bg-white/80 backdrop-blur-md shadow-lg p-1">
|
||||
<NuxtLink
|
||||
:to="localePath('/clientarea/orders')"
|
||||
class="px-4 py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap"
|
||||
:class="isClientAreaTabActive('/clientarea/orders') ? 'bg-primary text-primary-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200/50'"
|
||||
>
|
||||
{{ $t('cabinetNav.orders') }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
v-if="isSeller"
|
||||
:to="localePath('/clientarea/offers')"
|
||||
class="px-4 py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap"
|
||||
:class="isClientAreaTabActive('/clientarea/offers') ? 'bg-primary text-primary-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200/50'"
|
||||
>
|
||||
{{ $t('cabinetNav.myOffers') }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="localePath('/clientarea/addresses')"
|
||||
class="px-4 py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap"
|
||||
:class="isClientAreaTabActive('/clientarea/addresses') ? 'bg-primary text-primary-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200/50'"
|
||||
>
|
||||
{{ $t('cabinetNav.addresses') }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="localePath('/clientarea/profile')"
|
||||
class="px-4 py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap"
|
||||
:class="isClientAreaTabActive('/clientarea/profile') ? 'bg-primary text-primary-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200/50'"
|
||||
>
|
||||
{{ $t('cabinetNav.profile') }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="localePath('/clientarea/team')"
|
||||
class="px-4 py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap"
|
||||
:class="isClientAreaTabActive('/clientarea/team') ? 'bg-primary text-primary-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200/50'"
|
||||
>
|
||||
{{ $t('cabinetNav.team') }}
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Quote mode: Simple segmented input with search inside (white glass) -->
|
||||
<template v-if="catalogMode === 'quote'">
|
||||
<template v-else-if="catalogMode === 'quote'">
|
||||
<div class="flex items-center w-full rounded-full border border-white/40 bg-white/80 backdrop-blur-md shadow-lg divide-x divide-base-300/30">
|
||||
<!-- Product segment -->
|
||||
<button
|
||||
@@ -135,8 +177,19 @@
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Right: AI + Globe + Team + User (top aligned like logo) -->
|
||||
<!-- Right: Cabinet + AI + Globe + Team + User (top aligned like logo) -->
|
||||
<div class="flex items-start gap-1 flex-shrink-0 pt-4">
|
||||
<!-- Cabinet button (when logged in and not in client area) -->
|
||||
<NuxtLink
|
||||
v-if="loggedIn && !isClientArea"
|
||||
:to="localePath('/clientarea/orders')"
|
||||
class="w-8 h-8 rounded-full flex items-center justify-center transition-colors"
|
||||
:class="useWhiteText ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'"
|
||||
:title="$t('cabinetNav.cabinet')"
|
||||
>
|
||||
<Icon name="lucide:layout-dashboard" size="18" />
|
||||
</NuxtLink>
|
||||
|
||||
<!-- AI Assistant button -->
|
||||
<NuxtLink
|
||||
:to="localePath('/clientarea/ai')"
|
||||
@@ -310,6 +363,8 @@ const props = withDefaults(defineProps<{
|
||||
isCollapsed?: boolean
|
||||
// Home page flag for transparent background
|
||||
isHomePage?: boolean
|
||||
// Client area flag - shows cabinet tabs instead of search
|
||||
isClientArea?: boolean
|
||||
// Dynamic height for hero effect
|
||||
height?: number
|
||||
}>(), {
|
||||
@@ -334,10 +389,18 @@ defineEmits([
|
||||
])
|
||||
|
||||
const localePath = useLocalePath()
|
||||
const route = useRoute()
|
||||
const { locale, locales } = useI18n()
|
||||
const switchLocalePath = useSwitchLocalePath()
|
||||
const { t } = useI18n()
|
||||
|
||||
// Check if client area tab is active
|
||||
const isClientAreaTabActive = (path: string) => {
|
||||
const currentPath = route.path
|
||||
const localizedPath = localePath(path)
|
||||
return currentPath === localizedPath || currentPath.startsWith(localizedPath + '/')
|
||||
}
|
||||
|
||||
const inputRef = ref<HTMLInputElement>()
|
||||
const localSearchQuery = ref(props.searchQuery || '')
|
||||
const localQuantity = ref(props.quantity || '')
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
:show-active-mode="isCatalogSection"
|
||||
:is-collapsed="isHomePage ? heroIsCollapsed : isCatalogSection"
|
||||
:is-home-page="isHomePage"
|
||||
:is-client-area="isClientArea"
|
||||
@toggle-theme="toggleTheme"
|
||||
@set-catalog-mode="setCatalogMode"
|
||||
@sign-out="onClickSignOut"
|
||||
@@ -54,9 +55,9 @@
|
||||
</template>
|
||||
</MainNavigation>
|
||||
|
||||
<!-- Sub Navigation (section-specific tabs) - only for non-catalog/non-home sections -->
|
||||
<!-- Sub Navigation (section-specific tabs) - only for non-catalog/non-home/non-clientarea sections -->
|
||||
<SubNavigation
|
||||
v-if="!isHomePage && !isCatalogSection"
|
||||
v-if="!isHomePage && !isCatalogSection && !isClientArea"
|
||||
:section="currentSection"
|
||||
/>
|
||||
</div>
|
||||
@@ -174,8 +175,13 @@ const isCatalogSection = computed(() => {
|
||||
route.path.startsWith('/ru/catalog')
|
||||
})
|
||||
|
||||
// Client area detection (cabinet tabs in MainNavigation, no SubNav needed)
|
||||
const isClientArea = computed(() => {
|
||||
return route.path.includes('/clientarea')
|
||||
})
|
||||
|
||||
// Collapsible header logic - only for pages with SubNav
|
||||
const hasSubNav = computed(() => !isHomePage.value && !isCatalogSection.value)
|
||||
const hasSubNav = computed(() => !isHomePage.value && !isCatalogSection.value && !isClientArea.value)
|
||||
const canCollapse = computed(() => hasSubNav.value)
|
||||
const isHeaderCollapsed = computed(() => canCollapse.value && isCollapsed.value)
|
||||
|
||||
@@ -193,6 +199,7 @@ const headerContainerStyle = computed(() => {
|
||||
const mainStyle = computed(() => {
|
||||
if (isCatalogSection.value) return { paddingTop: '0' }
|
||||
if (isHomePage.value) return { paddingTop: `${heroBaseHeight.value}px` }
|
||||
if (isClientArea.value) return { paddingTop: '116px' } // Header only, no SubNav
|
||||
return { paddingTop: '154px' }
|
||||
})
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"cabinetNav": {
|
||||
"cabinet": "My Cabinet",
|
||||
"search": "Search",
|
||||
"catalog": "Catalog",
|
||||
"orders": "My orders",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"cabinetNav": {
|
||||
"cabinet": "Мой кабинет",
|
||||
"search": "Поиск",
|
||||
"catalog": "Каталог",
|
||||
"orders": "Мои заказы",
|
||||
|
||||
Reference in New Issue
Block a user