58 lines
1.2 KiB
TypeScript
58 lines
1.2 KiB
TypeScript
"use client"
|
|
|
|
import { useState } from "react"
|
|
import type { UserAccount } from "@/lib/accounts/types"
|
|
import { avatarColor, senderInitial } from "@/lib/sender-display"
|
|
import { cn } from "@/lib/utils"
|
|
|
|
interface AccountAvatarProps {
|
|
account: UserAccount
|
|
size?: "sm" | "md" | "lg"
|
|
className?: string
|
|
}
|
|
|
|
const sizeClasses = {
|
|
sm: "size-8 text-sm",
|
|
md: "size-10 text-base",
|
|
lg: "size-20 text-3xl",
|
|
} as const
|
|
|
|
export function AccountAvatar({
|
|
account,
|
|
size = "md",
|
|
className,
|
|
}: AccountAvatarProps) {
|
|
const [imageFailed, setImageFailed] = useState(false)
|
|
const initial = senderInitial(account.displayName)
|
|
const color = avatarColor(account.displayName)
|
|
|
|
if (account.avatarUrl && !imageFailed) {
|
|
return (
|
|
<img
|
|
src={account.avatarUrl}
|
|
alt=""
|
|
className={cn(
|
|
"shrink-0 rounded-full object-cover",
|
|
sizeClasses[size],
|
|
className,
|
|
)}
|
|
onError={() => setImageFailed(true)}
|
|
/>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"flex shrink-0 items-center justify-center rounded-full font-medium text-white",
|
|
sizeClasses[size],
|
|
className,
|
|
)}
|
|
style={{ backgroundColor: color }}
|
|
aria-hidden
|
|
>
|
|
{initial}
|
|
</div>
|
|
)
|
|
}
|