46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
import { fileDownloadUrl } from '@/business/files/api';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface UserAvatarProps {
|
|
readonly name: string;
|
|
readonly avatarUrl?: string | null;
|
|
readonly className?: string;
|
|
readonly fallbackClassName?: string;
|
|
readonly imageClassName?: string;
|
|
}
|
|
|
|
function initialsForName(name: string): string {
|
|
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
if (parts.length >= 2) {
|
|
return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
|
|
}
|
|
return (parts[0]?.slice(0, 2) || 'U').toUpperCase();
|
|
}
|
|
|
|
export function UserAvatar({
|
|
name,
|
|
avatarUrl,
|
|
className,
|
|
fallbackClassName,
|
|
imageClassName,
|
|
}: UserAvatarProps) {
|
|
return (
|
|
<span
|
|
className={cn(
|
|
'inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full border border-slate-700 bg-slate-800 text-xs font-semibold text-slate-300',
|
|
className,
|
|
)}
|
|
>
|
|
{avatarUrl ? (
|
|
<img
|
|
src={fileDownloadUrl(avatarUrl)}
|
|
alt=""
|
|
className={cn('h-full w-full object-cover', imageClassName)}
|
|
/>
|
|
) : (
|
|
<span className={fallbackClassName}>{initialsForName(name)}</span>
|
|
)}
|
|
</span>
|
|
);
|
|
}
|