AeThex-Connect/packages/ui/components/Avatar.tsx

92 lines
1.9 KiB
TypeScript

/**
* Avatar Component
* User avatar with status indicator
*/
import React from 'react';
export interface AvatarProps {
src?: string;
alt?: string;
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
status?: 'online' | 'offline' | 'busy' | 'away';
name?: string;
showStatus?: boolean;
}
export const Avatar: React.FC<AvatarProps> = ({
src,
alt,
size = 'md',
status = 'offline',
name,
showStatus = false,
}) => {
const sizeClasses = {
xs: 'w-6 h-6 text-xs',
sm: 'w-8 h-8 text-sm',
md: 'w-10 h-10 text-base',
lg: 'w-12 h-12 text-lg',
xl: 'w-16 h-16 text-2xl',
};
const statusColors = {
online: 'bg-green-500',
offline: 'bg-gray-500',
busy: 'bg-red-500',
away: 'bg-yellow-500',
};
const statusSizes = {
xs: 'w-1.5 h-1.5',
sm: 'w-2 h-2',
md: 'w-2.5 h-2.5',
lg: 'w-3 h-3',
xl: 'w-4 h-4',
};
// Generate initials from name
const getInitials = (name?: string) => {
if (!name) return '?';
return name
.split(' ')
.map(n => n[0])
.join('')
.toUpperCase()
.slice(0, 2);
};
return (
<div className="relative inline-block">
{src ? (
<img
src={src}
alt={alt || name}
className={`${sizeClasses[size]} rounded-full object-cover border-2 border-gray-700`}
/>
) : (
<div
className={`
${sizeClasses[size]} rounded-full
bg-gradient-to-br from-purple-600 to-pink-600
flex items-center justify-center
font-semibold text-white
border-2 border-gray-700
`}
>
{getInitials(name)}
</div>
)}
{showStatus && (
<span
className={`
absolute bottom-0 right-0
${statusSizes[size]} ${statusColors[status]}
rounded-full border-2 border-gray-900
`}
/>
)}
</div>
);
};