Files
cozsweet-frontend-nextjs/src/app/_components/user-message-avatar.tsx
T
admin 9deb320cf6 feat(profile)!: replace sidebar and add avatar navigation
Rename the global Sidebar route, UI, assets, analytics, and payment return context to Profile. Add accessible message-avatar navigation and preserve the source character across auth and logout flows.

BREAKING CHANGE: /sidebar has been removed; use /profile instead.
2026-07-21 18:08:12 +08:00

73 lines
1.9 KiB
TypeScript

"use client";
import Image from "next/image";
import type { AvatarInteractionProps } from "./avatar-interaction";
interface UserMessageAvatarVisualProps {
avatarUrl?: string | null;
className?: string;
size?: number | string;
}
export type UserMessageAvatarProps = UserMessageAvatarVisualProps &
AvatarInteractionProps;
export function UserMessageAvatar({
avatarUrl,
className,
size = 43,
onClick,
actionLabel,
analyticsKey,
}: UserMessageAvatarProps) {
const avatarClassName = [
"flex shrink-0 items-center justify-center overflow-hidden rounded-full border-2 border-(--color-avatar-border,#fbf3f5) bg-(--color-avatar-border,#fbf3f5) shadow-(--shadow-input-box,0_1px_2px_rgba(0,0,0,0.1))",
onClick
? "cursor-pointer p-0 transition-transform duration-150 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-accent active:scale-96"
: undefined,
className,
]
.filter(Boolean)
.join(" ");
const avatarStyle = { width: size, height: size };
const imageSize = typeof size === "number" ? size : 64;
const hasUserAvatar = Boolean(avatarUrl && avatarUrl.length > 0);
const image = (
<Image
src={hasUserAvatar ? avatarUrl! : "/images/avatar/placeholder.png"}
alt={hasUserAvatar ? "" : "Guest"}
width={imageSize}
height={imageSize}
className="size-full object-cover"
/>
);
if (onClick) {
return (
<button
type="button"
className={avatarClassName}
style={avatarStyle}
aria-label={actionLabel}
data-analytics-key={analyticsKey}
data-analytics-label={actionLabel}
onClick={onClick}
>
{image}
</button>
);
}
return (
<div
className={avatarClassName}
style={avatarStyle}
aria-label={hasUserAvatar ? "User avatar" : "Guest avatar"}
>
{image}
</div>
);
}