Show profile avatar in top nav when user has one set

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Janpeter Visser 2026-04-20 02:21:00 +02:00
parent d35889b5dc
commit f9f04a9f2d
5 changed files with 36 additions and 6 deletions

View file

@ -10,6 +10,7 @@ import {
} from "lucide-react";
import { signOutAction } from "@/app/auth-actions";
import type { AuthState } from "@/lib/auth/session";
import { ProfileAvatar } from "@/components/profile/profile-avatar";
import {
DropdownMenu,
DropdownMenuContent,
@ -21,13 +22,25 @@ import {
type AccountMenuProps = {
authState: AuthState;
navAvatarUrl: string | null;
};
export function AccountMenu({ authState }: AccountMenuProps) {
export function AccountMenu({ authState, navAvatarUrl }: AccountMenuProps) {
const showAvatar = authState.isAuthenticated && navAvatarUrl;
return (
<DropdownMenu>
<DropdownMenuTrigger aria-label="Account menu">
<CircleUserRoundIcon className="size-4" />
{showAvatar ? (
<ProfileAvatar
avatarUrl={navAvatarUrl}
displayName={null}
email={authState.email}
size="xs"
/>
) : (
<CircleUserRoundIcon className="size-4" />
)}
<span className="hidden sm:inline">Account</span>
</DropdownMenuTrigger>
<DropdownMenuContent>

View file

@ -1,5 +1,6 @@
import type { ReactNode } from "react";
import { getAuthState } from "@/lib/auth/session";
import { getNavAvatarUrlForCurrentUser } from "@/lib/profile/service";
import { BottomNav } from "@/components/navigation/bottom-nav";
import { TopNav } from "@/components/navigation/top-nav";
import { cn } from "@/lib/utils";
@ -14,11 +15,14 @@ export async function AppShell({
contentClassName,
}: AppShellProps) {
const authState = await getAuthState();
const navAvatarUrl = authState.userId
? await getNavAvatarUrlForCurrentUser(authState.userId)
: null;
return (
<main className="app-page">
<div className="mx-auto flex min-h-screen w-full max-w-6xl flex-col gap-8">
<TopNav authState={authState} />
<TopNav authState={authState} navAvatarUrl={navAvatarUrl} />
<div className={cn("flex-1", contentClassName)}>{children}</div>
<BottomNav />
</div>

View file

@ -14,9 +14,10 @@ import { cn } from "@/lib/utils";
type TopNavProps = {
authState: AuthState;
navAvatarUrl: string | null;
};
export function TopNav({ authState }: TopNavProps) {
export function TopNav({ authState, navAvatarUrl }: TopNavProps) {
const pathname = usePathname();
const useCompactBottomNav = shouldUseBottomNav(pathname);
@ -64,7 +65,7 @@ export function TopNav({ authState }: TopNavProps) {
<div className="ml-auto flex flex-wrap items-center gap-2">
<ThemeMenu />
<AccountMenu authState={authState} />
<AccountMenu authState={authState} navAvatarUrl={navAvatarUrl} />
</div>
</div>
</header>

View file

@ -4,11 +4,12 @@ type ProfileAvatarProps = {
avatarUrl: string | null;
displayName: string | null;
email?: string | null;
size?: "sm" | "md" | "lg";
size?: "xs" | "sm" | "md" | "lg";
className?: string;
};
const avatarSizeClasses = {
xs: "size-6 text-[10px]",
sm: "size-12 text-sm",
md: "size-16 text-base",
lg: "size-20 text-xl",