feat: show avatar image in top nav when user has one
All checks were successful
CI / ci (push) Successful in 1m13s
CI / e2e (push) Has been skipped
CI / deploy (push) Successful in 14s

UserMenu now fetches the user's profile and displays their avatar
image in the nav button instead of the default circle-user icon.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 23:07:28 +02:00
parent b647e23f91
commit af58145fe1

View File

@@ -1,12 +1,17 @@
import { Link } from "@tanstack/react-router"; import { Link } from "@tanstack/react-router";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { useLogout } from "../hooks/useAuth"; import { useAuth, useLogout } from "../hooks/useAuth";
import { usePublicProfile } from "../hooks/useProfile";
import { LucideIcon } from "../lib/iconData"; import { LucideIcon } from "../lib/iconData";
export function UserMenu() { export function UserMenu() {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const menuRef = useRef<HTMLDivElement>(null); const menuRef = useRef<HTMLDivElement>(null);
const { logout } = useLogout(); const { logout } = useLogout();
const { data: auth } = useAuth();
const userId = auth?.user?.id ? Number(auth.user.id) : null;
const { data: profile } = usePublicProfile(userId);
const avatarUrl = profile?.avatarImageUrl;
useEffect(() => { useEffect(() => {
if (!open) return; if (!open) return;
@@ -24,9 +29,17 @@ export function UserMenu() {
<button <button
type="button" type="button"
onClick={() => setOpen((prev) => !prev)} onClick={() => setOpen((prev) => !prev)}
className="flex items-center justify-center w-8 h-8 rounded-full text-gray-500 hover:text-gray-700 hover:bg-gray-100 transition-colors" className="flex items-center justify-center w-8 h-8 rounded-full text-gray-500 hover:text-gray-700 hover:bg-gray-100 transition-colors overflow-hidden"
> >
{avatarUrl ? (
<img
src={avatarUrl}
alt="Profile"
className="w-8 h-8 rounded-full object-cover"
/>
) : (
<LucideIcon name="circle-user" size={22} /> <LucideIcon name="circle-user" size={22} />
)}
</button> </button>
{open && ( {open && (
<div className="absolute right-0 mt-1 w-40 bg-white rounded-lg shadow-lg border border-gray-200 py-1 z-50"> <div className="absolute right-0 mt-1 w-40 bg-white rounded-lg shadow-lg border border-gray-200 py-1 z-50">