Files
forkmessager/apps/web/src/components/Avatar.tsx
Халимов Рустам b4b4b8e0d3 Original
2026-03-10 21:11:59 +03:00

61 lines
1.5 KiB
TypeScript

import { memo } from 'react';
import { getInitials, generateAvatarColor } from '../lib/utils';
interface AvatarProps {
src?: string | null;
name: string;
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
className?: string;
online?: boolean;
}
const sizeClasses = {
xs: 'w-6 h-6 text-[10px]',
sm: 'w-8 h-8 text-xs',
md: 'w-10 h-10 text-sm',
lg: 'w-12 h-12 text-base',
xl: 'w-20 h-20 text-xl',
} as const;
const onlineDotSize = {
xs: 'w-1.5 h-1.5 border',
sm: 'w-2 h-2 border',
md: 'w-2.5 h-2.5 border-2',
lg: 'w-3 h-3 border-2',
xl: 'w-4 h-4 border-2',
} as const;
function AvatarInner({ src, name, size = 'md', className = '', online }: AvatarProps) {
const sizeClass = sizeClasses[size];
const initials = getInitials(name || '?');
const gradientClass = generateAvatarColor(name || '');
return (
<div className={`relative shrink-0 ${className}`}>
{src ? (
<img
src={src}
alt={name}
className={`${sizeClass} rounded-full object-cover`}
/>
) : (
<div
className={`${sizeClass} rounded-full bg-gradient-to-br ${gradientClass} flex items-center justify-center text-white font-medium`}
>
{initials}
</div>
)}
{online !== undefined && (
<div
className={`absolute bottom-0 right-0 ${onlineDotSize[size]} rounded-full border-surface ${
online ? 'bg-emerald-500' : 'bg-zinc-500'
}`}
/>
)}
</div>
);
}
const Avatar = memo(AvatarInner);
export default Avatar;