Improve mobile navbar UX with icon navigation
- Add mobile navigation icons for Events, Market, and Chat routes - Remove route items from mobile dropdown to reduce clutter - Mobile dropdown now focuses on user account management only - Remove Home route from desktop navigation (logo serves as home) - Add active states and hover effects for mobile route icons - Preserve chat notification badges and market preloading indicators 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a811040a34
commit
cd5dc008b2
1 changed files with 43 additions and 22 deletions
|
|
@ -6,7 +6,7 @@ import { useTheme } from '@/components/theme-provider'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
|
||||||
import { Sun, Moon, Menu, X, User, LogOut, Ticket, Wallet, MessageSquare, Activity, ShoppingCart, Store } from 'lucide-vue-next'
|
import { Sun, Moon, Menu, X, User, LogOut, Ticket, Wallet, MessageSquare, Activity, ShoppingCart, Store, Calendar, ShoppingBag } from 'lucide-vue-next'
|
||||||
import LanguageSwitcher from '@/components/LanguageSwitcher.vue'
|
import LanguageSwitcher from '@/components/LanguageSwitcher.vue'
|
||||||
import LoginDialog from '@/components/auth/LoginDialog.vue'
|
import LoginDialog from '@/components/auth/LoginDialog.vue'
|
||||||
import ProfileDialog from '@/components/auth/ProfileDialog.vue'
|
import ProfileDialog from '@/components/auth/ProfileDialog.vue'
|
||||||
|
|
@ -100,7 +100,7 @@ const handleLogout = async () => {
|
||||||
|
|
||||||
<!-- Desktop Navigation -->
|
<!-- Desktop Navigation -->
|
||||||
<div class="hidden md:flex gap-4 lg:gap-6 xl:gap-8">
|
<div class="hidden md:flex gap-4 lg:gap-6 xl:gap-8">
|
||||||
<router-link v-for="item in navigation" :key="item.name" :to="item.href"
|
<router-link v-for="item in navigation.filter(nav => nav.href !== '/')" :key="item.name" :to="item.href"
|
||||||
class="text-muted-foreground hover:text-foreground transition-colors flex items-center gap-2 text-sm lg:text-base xl:text-lg relative"
|
class="text-muted-foreground hover:text-foreground transition-colors flex items-center gap-2 text-sm lg:text-base xl:text-lg relative"
|
||||||
:class="{
|
:class="{
|
||||||
'text-foreground': $route.path === item.href
|
'text-foreground': $route.path === item.href
|
||||||
|
|
@ -198,9 +198,37 @@ const handleLogout = async () => {
|
||||||
<LanguageSwitcher />
|
<LanguageSwitcher />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Mobile Chat Button (only show when authenticated) -->
|
<!-- Mobile Navigation Icons (only show when authenticated) -->
|
||||||
<router-link v-if="auth.isAuthenticated.value" to="/chat"
|
<div v-if="auth.isAuthenticated.value" class="md:hidden flex items-center gap-1">
|
||||||
class="md:hidden relative inline-flex items-center justify-center rounded-md p-2 text-foreground hover:text-foreground/90 hover:bg-accent transition-colors">
|
<!-- Events Button -->
|
||||||
|
<router-link to="/events"
|
||||||
|
class="relative inline-flex items-center justify-center rounded-md p-2 text-foreground hover:text-foreground/90 hover:bg-accent transition-colors"
|
||||||
|
:class="{
|
||||||
|
'text-primary bg-accent': $route.path === '/events'
|
||||||
|
}">
|
||||||
|
<span class="sr-only">Events</span>
|
||||||
|
<Calendar class="h-5 w-5" />
|
||||||
|
</router-link>
|
||||||
|
|
||||||
|
<!-- Market Button -->
|
||||||
|
<router-link to="/market"
|
||||||
|
class="relative inline-flex items-center justify-center rounded-md p-2 text-foreground hover:text-foreground/90 hover:bg-accent transition-colors"
|
||||||
|
:class="{
|
||||||
|
'text-primary bg-accent': $route.path.startsWith('/market')
|
||||||
|
}">
|
||||||
|
<span class="sr-only">Market</span>
|
||||||
|
<ShoppingBag class="h-5 w-5" />
|
||||||
|
<!-- Market preloading indicator -->
|
||||||
|
<div v-if="marketPreloader.isPreloading"
|
||||||
|
class="absolute -top-0.5 -right-0.5 w-2 h-2 bg-blue-500 rounded-full animate-pulse"></div>
|
||||||
|
</router-link>
|
||||||
|
|
||||||
|
<!-- Chat Button -->
|
||||||
|
<router-link to="/chat"
|
||||||
|
class="relative inline-flex items-center justify-center rounded-md p-2 text-foreground hover:text-foreground/90 hover:bg-accent transition-colors"
|
||||||
|
:class="{
|
||||||
|
'text-primary bg-accent': $route.path === '/chat'
|
||||||
|
}">
|
||||||
<span class="sr-only">Chat</span>
|
<span class="sr-only">Chat</span>
|
||||||
<MessageSquare class="h-5 w-5" />
|
<MessageSquare class="h-5 w-5" />
|
||||||
<Badge v-if="totalUnreadMessages > 0"
|
<Badge v-if="totalUnreadMessages > 0"
|
||||||
|
|
@ -208,6 +236,7 @@ const handleLogout = async () => {
|
||||||
{{ totalUnreadMessages > 99 ? '99+' : totalUnreadMessages }}
|
{{ totalUnreadMessages > 99 ? '99+' : totalUnreadMessages }}
|
||||||
</Badge>
|
</Badge>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Mobile menu button -->
|
<!-- Mobile menu button -->
|
||||||
<Button variant="ghost" size="icon" @click="toggleMenu"
|
<Button variant="ghost" size="icon" @click="toggleMenu"
|
||||||
|
|
@ -276,16 +305,8 @@ const handleLogout = async () => {
|
||||||
<LanguageSwitcher />
|
<LanguageSwitcher />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<router-link v-for="item in navigation.filter(nav => nav.href !== '/chat')" :key="item.name" :to="item.href"
|
<!-- Navigation routes removed from mobile dropdown for better UX -->
|
||||||
class="flex items-center gap-2 px-3 py-2 text-base font-medium text-muted-foreground hover:text-foreground transition-colors relative"
|
<!-- Routes are now available as icons in the top navigation -->
|
||||||
:class="{
|
|
||||||
'text-foreground': $route.path === item.href
|
|
||||||
}" @click="isOpen = false">
|
|
||||||
<span>{{ item.name }}</span>
|
|
||||||
<!-- Market preloading indicator -->
|
|
||||||
<div v-if="item.href === '/market' && marketPreloader.isPreloading"
|
|
||||||
class="w-2 h-2 bg-blue-500 rounded-full animate-pulse"></div>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue