web/app/components/SiteHeader.vue
Yoga Pangestu 0c732e71cf feat: update sidebar and header layout; fix dnd-kit-vue package error
- Fixed import error for `dnd-kit-vue` by installing the package.
- Moved user navigation from sidebar to header, adding a dropdown for account options.
- Added homepage and notification icons to the header.
- Implemented sticky header functionality during scroll.
- Grouped sidebar menu items under a "Master" label for better organization.
- Updated relevant components and package.json to include new dependencies.
2026-07-23 23:43:04 +07:00

102 lines
3.4 KiB
Vue

<script setup lang="ts">
import {
Avatar,
AvatarFallback,
AvatarImage,
} from '@/components/ui/avatar'
import { Button } from '@/components/ui/button'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { Separator } from '@/components/ui/separator'
import { SidebarTrigger } from '@/components/ui/sidebar'
import {
Bell,
CreditCard,
Home,
LogOut,
UserCircle,
} from "@lucide/vue"
const user = {
name: "shadcn",
email: "m@example.com",
avatar: "/avatars/shadcn.jpg",
}
</script>
<template>
<header
class="sticky top-0 z-10 flex h-(--header-height) shrink-0 items-center gap-2 border-b bg-background transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-(--header-height)">
<div class="flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6">
<SidebarTrigger class="-ml-1" />
<Separator orientation="vertical" class="mx-2 data-[orientation=vertical]:h-4" />
<div class="ml-auto flex items-center gap-2">
<Button variant="ghost" size="icon" class="size-8" as-child>
<a href="/">
<Home class="size-4" />
<span class="sr-only">Homepage</span>
</a>
</Button>
<Button variant="ghost" size="icon" class="size-8">
<Bell class="size-4" />
<span class="sr-only">Notifications</span>
</Button>
<Separator orientation="vertical" class="mx-1 data-[orientation=vertical]:h-4" />
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="ghost" size="icon" class="size-8 rounded-full">
<Avatar class="h-8 w-8">
<AvatarImage :src="user.avatar" :alt="user.name" />
<AvatarFallback class="rounded-lg">
CN
</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-56 rounded-lg" side="bottom" align="end">
<DropdownMenuLabel class="p-0 font-normal">
<div class="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
<Avatar class="h-8 w-8 rounded-lg">
<AvatarImage :src="user.avatar" :alt="user.name" />
<AvatarFallback class="rounded-lg">
CN
</AvatarFallback>
</Avatar>
<div class="grid flex-1 text-left text-sm leading-tight">
<span class="truncate font-medium">{{ user.name }}</span>
<span class="text-muted-foreground truncate text-xs">
{{ user.email }}
</span>
</div>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<UserCircle />
Account
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard />
Billing
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<LogOut />
Log out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</header>
</template>