frontend/src/components/Navbar/NavBar.vue

170 lines
3.5 KiB
Vue
Raw Normal View History

2025-09-12 23:48:21 +03:00
<script setup>
2025-09-13 20:38:35 +03:00
import { computed, h, onMounted, ref, watch } from 'vue'
2025-09-12 23:48:21 +03:00
import { NMenu, NButton, NDrawer, NIcon } from 'naive-ui'
import MenuIcon from '@/components/Navbar/MenuIcon.vue'
import { RouterLink, useRoute } from 'vue-router'
2025-09-13 20:38:35 +03:00
import { useAuthStore } from '@/stores/authStore'
const authStore = useAuthStore()
2025-09-12 23:48:21 +03:00
const showMobileMenu = ref(false)
const route = useRoute()
const activeKey = ref('collection')
2025-09-13 20:38:35 +03:00
const mainMenu = computed(() => {
return [
{ label: 'Collection', key: 'collection' },
{ label: 'Charts', key: 'charts' },
{ label: 'Parsers', key: 'parsers' },
2025-11-02 23:40:44 +03:00
{ label: 'Zero prices', key: 'zeroprices' },
2025-09-13 20:38:35 +03:00
]
})
2025-09-12 23:48:21 +03:00
2025-09-13 20:38:35 +03:00
const authMenu = computed(() => {
2025-09-14 11:39:37 +03:00
if (!authStore.isAuthenticated) {
2025-09-13 20:38:35 +03:00
return [
{ label: 'Login', key: 'login' }
]
}
return [
2025-10-29 20:58:47 +03:00
{ label: 'Labels', key: 'labels' },
2025-09-13 20:38:35 +03:00
{ label: 'Personal', key: 'personal' },
]
})
2025-09-12 23:48:21 +03:00
const windowWidth = ref(window.innerWidth)
onMounted(() => {
const handleResize = () => {
windowWidth.value = window.innerWidth
}
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
})
watch(() => route.name, (newName) => {
activeKey.value = newName
})
const renderLabel = (option) => {
return h(
RouterLink,
{
to: { name: option.key },
class: 'nav-link',
style: 'text-decoration: none; color: inherit;'
},
{ default: () => option.label }
)
}
</script>
<template>
<header class="navbar">
<div class="logo">Merch tracker</div>
<n-menu
2025-09-13 20:38:35 +03:00
class="main-menu"
:options="mainMenu"
2025-09-12 23:48:21 +03:00
mode="horizontal"
:collapsed="false"
:value="activeKey"
@update:value="activeKey = $event"
2025-09-14 11:39:37 +03:00
v-if="authStore.isAuthenticated && windowWidth > 768"
2025-09-12 23:48:21 +03:00
:render-label="renderLabel"
/>
2025-09-13 20:38:35 +03:00
<div class="auth-menu-container">
<n-menu
class="auth-menu"
:options="authMenu"
mode="horizontal"
:collapsed="false"
:value="activeKey"
@update:value="activeKey = $event"
v-if="windowWidth > 768"
:render-label="renderLabel"
/>
</div>
2025-09-12 23:48:21 +03:00
<n-button
class="menu-mobile-button"
@click="showMobileMenu = !showMobileMenu"
>
<n-icon :size="34">
<MenuIcon />
</n-icon>
</n-button>
<n-drawer v-model:show="showMobileMenu" placement="right">
<n-menu
2025-09-14 11:39:37 +03:00
:options="authStore.isAuthenticated ? [...mainMenu, ...authMenu] : authMenu"
2025-09-12 23:48:21 +03:00
mode="vertical"
:value="activeKey"
@update:value="activeKey = $event; showMobileMenu = false"
:render-label="renderLabel"
/>
</n-drawer>
</header>
</template>
<style>
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
height: 60px;
background: #fff;
2025-09-25 20:40:11 +03:00
border-bottom: 2px solid #18a058;
2025-09-12 23:48:21 +03:00
position: relative;
z-index: 10;
}
.logo {
font-weight: bold;
font-size: 1.2rem;
flex-shrink: 0;
}
2025-09-13 20:38:35 +03:00
.main-menu {
display: flex;
margin-right: auto;
}
.auth-menu-container {
2025-09-12 23:48:21 +03:00
display: flex;
2025-09-13 20:38:35 +03:00
align-items: center;
margin-left: auto;
2025-10-29 20:58:47 +03:00
min-width: 250px;
2025-09-13 20:38:35 +03:00
padding-right: 16px;
box-sizing: border-box;
}
.auth-menu {
margin-left: 20px;
2025-09-12 23:48:21 +03:00
}
.menu-mobile-button {
display: none;
width: 34px;
height: 34px;
padding: 0;
margin: 0;
border-radius: 8px;
background: transparent;
align-items: center;
justify-content: flex-start;
flex-shrink: 0;
}
@media (max-width: 768px) {
.menu-mobile-button {
display: inline-flex;
}
}
</style>