forked from BRETT/BRETT
Initial Commit
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
<script setup lang="ts">
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
|
||||
const { user, can, logout } = useAuth()
|
||||
const { uniform, toggle: toggleGridMode } = useGridMode()
|
||||
const { open: paletteOpen } = useCommandPalette()
|
||||
const route = useRoute()
|
||||
|
||||
async function onLogoClick(e: MouseEvent) {
|
||||
if (route.path !== '/') return
|
||||
e.preventDefault()
|
||||
await refreshNuxtData()
|
||||
}
|
||||
|
||||
const initials = computed(() => user.value?.name.slice(0, 2).toUpperCase() ?? '')
|
||||
|
||||
async function onLogout() {
|
||||
await logout()
|
||||
await navigateTo('/')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header class="sticky top-0 z-10 flex h-(--header-height) shrink-0 items-center gap-2 border-b bg-background">
|
||||
<div class="flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6">
|
||||
<NuxtLink
|
||||
to="/"
|
||||
class="mr-2 font-logo text-[2.4rem] leading-none tracking-tight transition-colors hover:text-accent"
|
||||
@click="onLogoClick"
|
||||
>
|
||||
BRETT
|
||||
</NuxtLink>
|
||||
<UploadPopover />
|
||||
<Button variant="ghost" as-child>
|
||||
<NuxtLink to="/users" class="flex items-center gap-1.5">
|
||||
<Icon name="ph:users-fill" class="size-4" />
|
||||
Benutzer
|
||||
</NuxtLink>
|
||||
</Button>
|
||||
<Button v-if="can('admin.access')" variant="ghost" as-child>
|
||||
<NuxtLink to="/admin" class="flex items-center gap-1.5">
|
||||
<Icon name="ph:shield-fill" class="size-4" />
|
||||
Admin
|
||||
</NuxtLink>
|
||||
</Button>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-auto flex h-9 cursor-pointer items-center gap-2 rounded-md border bg-muted/40 px-3 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"
|
||||
aria-label="Schnellsuche öffnen (Strg+K)"
|
||||
@click="paletteOpen = true"
|
||||
>
|
||||
<Icon name="ph:magnifying-glass-fill" class="size-4" />
|
||||
<span class="hidden text-left sm:inline">Suchen…</span>
|
||||
<kbd class="hidden rounded-sm border bg-background px-1.5 text-xs sm:inline">Strg K</kbd>
|
||||
</button>
|
||||
<div class="flex items-center gap-3">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
@click="toggleGridMode"
|
||||
>
|
||||
<Icon name="ph:grid-nine-fill" v-if="uniform" class="size-5" />
|
||||
<Icon name="ph:squares-four-fill" v-else class="size-5" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ uniform ? 'Bento-Layout' : 'Einheitliche Größe' }}</TooltipContent>
|
||||
</Tooltip>
|
||||
<ThemeSelector />
|
||||
<template v-if="user">
|
||||
<NotificationBell />
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger class="flex cursor-pointer items-center gap-2 rounded-md px-1 py-0.5 outline-none hover:bg-accent">
|
||||
<Avatar class="size-8">
|
||||
<AvatarImage v-if="user.avatarUrl" :src="user.avatarUrl" :alt="user.name" />
|
||||
<AvatarFallback
|
||||
class="text-xs"
|
||||
:style="user.color ? { backgroundColor: user.color, color: '#fff' } : undefined"
|
||||
>
|
||||
{{ initials }}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<span
|
||||
class="text-sm font-medium"
|
||||
:style="user.color ? { color: user.color } : undefined"
|
||||
>{{ user.name }}</span>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" class="w-44">
|
||||
<DropdownMenuLabel class="truncate">
|
||||
{{ user.name }}
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem as-child>
|
||||
<NuxtLink :to="`/user/${user.id}`" class="flex items-center gap-2">
|
||||
<Icon name="ph:user-fill" class="size-4" />
|
||||
Profil
|
||||
</NuxtLink>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem as-child>
|
||||
<NuxtLink to="/settings" class="flex items-center gap-2">
|
||||
<Icon name="ph:gear-fill" class="size-4" />
|
||||
Einstellungen
|
||||
</NuxtLink>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem variant="destructive" class="flex items-center gap-2" @click="onLogout">
|
||||
<Icon name="ph:sign-out-fill" class="size-4" />
|
||||
Ausloggen
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</template>
|
||||
<template v-else>
|
||||
<Button variant="ghost" as-child>
|
||||
<NuxtLink to="/login">Login</NuxtLink>
|
||||
</Button>
|
||||
<Button as-child>
|
||||
<NuxtLink to="/register">Registrieren</NuxtLink>
|
||||
</Button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
Reference in New Issue
Block a user