Share one user avatar between the rail and the profile page

UserAvatar (src/components/general/user-avatar.tsx) replaces the
profile page's ProfileAvatar and the rail's initials chip, so the rail
shows the user's photo too.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-19 05:35:42 +01:00
co-authored by Claude Opus 5.5
parent 02ed47dd86
commit b1023ba8ff
4 changed files with 79 additions and 39 deletions
@@ -1,32 +0,0 @@
import Img from "@moduletrace/twui/layout/Img";
import Span from "@moduletrace/twui/layout/Span";
type Props = {
src?: string;
initials: string;
};
/**
* 64px round photo, or the initials on sunken paper when there is none.
* Same treatment as the account row in the rail, just larger.
*/
export default function ProfileAvatar({ src, initials }: Props) {
if (src) {
return (
<Img
src={src}
alt="Your photo"
className="size-16 shrink-0 rounded-full object-cover bg-sunken"
/>
);
}
return (
<Span
className="size-16 shrink-0 rounded-full bg-sunken flex items-center justify-center text-lg font-bold leading-none text-ink"
aria-hidden
>
{initials || "?"}
</Span>
);
}
@@ -6,7 +6,7 @@ import Button from "@moduletrace/twui/layout/Button";
import imageInputToBase64, {
type ImageInputToBase64FunctionReturn,
} from "@moduletrace/twui/utils/form/imageInputToBase64";
import ProfileAvatar from "./profile-avatar";
import UserAvatar from "@/src/components/general/user-avatar";
type Props = {
saved_src?: string;
@@ -32,7 +32,12 @@ export default function ProfilePhotoField({
return (
<Row className="w-full gap-4! flex-nowrap items-center">
<ProfileAvatar src={preview_src} initials={initials} />
<UserAvatar
src={preview_src}
initials={initials}
alt="Your photo"
size="lg"
/>
<Stack className="gap-2! min-w-0">
<Row className="gap-2!">
<Button