This commit is contained in:
84
app/components/UserMenu.vue
Normal file
84
app/components/UserMenu.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<AppDropdown
|
||||
:open="open"
|
||||
@close="open = false"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="flex rounded-full border border-kestrel-border bg-kestrel-surface p-0.5 transition-colors hover:bg-kestrel-border hover:border-kestrel-accent"
|
||||
aria-label="User menu"
|
||||
:aria-expanded="open"
|
||||
aria-haspopup="true"
|
||||
@click="open = !open"
|
||||
>
|
||||
<img
|
||||
v-if="user?.avatar_url"
|
||||
:src="user.avatar_url"
|
||||
:alt="user.identifier"
|
||||
class="h-8 w-8 rounded-full object-cover"
|
||||
>
|
||||
<span
|
||||
v-else
|
||||
class="flex h-8 w-8 items-center justify-center rounded-full bg-kestrel-border text-xs font-medium text-kestrel-text"
|
||||
>
|
||||
{{ initials }}
|
||||
</span>
|
||||
</button>
|
||||
<template #menu>
|
||||
<NuxtLink
|
||||
to="/account"
|
||||
class="kestrel-context-menu-item"
|
||||
role="menuitem"
|
||||
@click="open = false"
|
||||
>
|
||||
Profile
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
to="/settings"
|
||||
class="kestrel-context-menu-item"
|
||||
role="menuitem"
|
||||
@click="open = false"
|
||||
>
|
||||
Settings
|
||||
</NuxtLink>
|
||||
<button
|
||||
type="button"
|
||||
class="kestrel-context-menu-item-danger w-full"
|
||||
role="menuitem"
|
||||
@click="onSignOut"
|
||||
>
|
||||
Sign out
|
||||
</button>
|
||||
</template>
|
||||
</AppDropdown>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['signout'])
|
||||
|
||||
const open = ref(false)
|
||||
|
||||
const initials = computed(() => {
|
||||
const id = props.user?.identifier ?? ''
|
||||
const parts = id.trim().split(/\s+/)
|
||||
if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase()
|
||||
return id.slice(0, 2).toUpperCase() || '?'
|
||||
})
|
||||
|
||||
function onSignOut() {
|
||||
open.value = false
|
||||
emit('signout')
|
||||
}
|
||||
|
||||
const route = useRoute()
|
||||
watch(() => route.path, () => {
|
||||
open.value = false
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user