diff --git a/src/components/layout/top-bar.tsx b/src/components/layout/top-bar.tsx index b6745c854..48109553d 100644 --- a/src/components/layout/top-bar.tsx +++ b/src/components/layout/top-bar.tsx @@ -8,10 +8,11 @@ import { Monitor, Moon, Settings, + Shield, Sun, - User, } from "lucide-react"; import { Logo } from "@/components/ui/logo"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import Link from "next/link"; import { useAuth, useLogout } from "@/hooks/use-auth"; import { useTheme } from "@/components/providers"; @@ -27,11 +28,21 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +function getInitials(name: string): string { + return name + .split(/[\s._-]+/) + .slice(0, 2) + .map((s) => s[0]?.toUpperCase() ?? "") + .join(""); +} + export function TopBar() { const { user, isLoading } = useAuth(); const logout = useLogout(); const { theme, setTheme } = useTheme(); const { t } = useTranslations(); + const avatarUrl = user?.avatarUrl ?? null; + const isAdmin = user?.role === "ADMIN"; const themeIcon = theme === "system" ? ( @@ -77,7 +88,14 @@ export function TopBar() { // the focus indicator without replacing it. className="text-muted-foreground hover:text-foreground flex min-h-11 min-w-11 items-center gap-1.5 rounded-md px-2 py-1.5 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2" > - + + {avatarUrl && ( + + )} + + {getInitials(user.username)} + + {user.username} @@ -94,6 +112,14 @@ export function TopBar() { {t("nav.notifications")} + {isAdmin && ( + + + + {t("nav.admin")} + + + )} {/* v1.4.36 W4e — About moved into the Admin Console (`/admin/about`). The dropdown entry was redundant for the small audience that still reaches it (admins