feat(layout): show avatar/login state in the top-right menu trigger
Replace the hamburger icon on the fixed top-right menu button with a context-aware affordance: the user's avatar when logged in (first initial when they have no picture), or a login icon when logged out. Opens the same profile/menu sheet either way; aria-label reflects the state. overflow-hidden + the avatar filling the round button keeps it clipped to the chip. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4ad776b26f
commit
ed1ef89f70
1 changed files with 16 additions and 4 deletions
|
|
@ -2,13 +2,16 @@
|
|||
import { ref, type Component } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Menu } from 'lucide-vue-next'
|
||||
import { LogIn } from 'lucide-vue-next'
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetTrigger,
|
||||
} from '@/components/ui/sheet'
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import { useAuth } from '@/composables/useAuthService'
|
||||
import { useCurrentUserAvatar } from '@/composables/useCurrentUserAvatar'
|
||||
import ProfileSheetContent from './ProfileSheetContent.vue'
|
||||
|
||||
export interface SidebarNavItem {
|
||||
|
|
@ -35,6 +38,9 @@ const { t } = useI18n()
|
|||
const router = useRouter()
|
||||
const open = ref(false)
|
||||
|
||||
const { isAuthenticated } = useAuth()
|
||||
const { pictureUrl, displayName, fallbackInitial } = useCurrentUserAvatar()
|
||||
|
||||
function handleClick(item: SidebarNavItem) {
|
||||
if (item.path) router.push(item.path)
|
||||
item.onClick?.()
|
||||
|
|
@ -46,11 +52,17 @@ function handleClick(item: SidebarNavItem) {
|
|||
<Sheet v-model:open="open">
|
||||
<SheetTrigger as-child>
|
||||
<button
|
||||
class="fixed top-0 right-0 z-40 m-3 inline-flex items-center justify-center rounded-full border bg-background/90 backdrop-blur supports-[backdrop-filter]:bg-background/60 h-9 w-9 text-muted-foreground hover:text-foreground hover:bg-accent transition-colors shadow-sm"
|
||||
class="fixed top-0 right-0 z-40 m-3 inline-flex items-center justify-center overflow-hidden rounded-full border bg-background/90 backdrop-blur supports-[backdrop-filter]:bg-background/60 h-9 w-9 text-muted-foreground hover:text-foreground hover:bg-accent transition-colors shadow-sm"
|
||||
style="margin-top: calc(env(safe-area-inset-top) + 0.75rem); margin-right: calc(env(safe-area-inset-right) + 0.75rem)"
|
||||
:aria-label="t('common.nav.menu')"
|
||||
:aria-label="isAuthenticated ? t('common.nav.profile') : t('common.nav.login')"
|
||||
>
|
||||
<Menu class="w-5 h-5" />
|
||||
<!-- Logged in: avatar (image, or first initial). Logged out: a
|
||||
login icon. Opens the same profile/menu sheet either way. -->
|
||||
<Avatar v-if="isAuthenticated" class="h-full w-full">
|
||||
<AvatarImage v-if="pictureUrl" :src="pictureUrl" :alt="displayName ?? ''" />
|
||||
<AvatarFallback>{{ fallbackInitial || '?' }}</AvatarFallback>
|
||||
</Avatar>
|
||||
<LogIn v-else class="w-5 h-5" />
|
||||
</button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="right" class="w-80 sm:w-96 max-w-full overflow-y-auto overflow-x-hidden">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue