import React, { useEffect, useState } from 'react';
/**
* AvatarData interface defines the structure for avatar data across the application.
* This standardized format ensures consistent avatar representation.
*
* @property src - URL to the avatar image (optional)
* @property color - Background color for initials fallback (optional, will be generated if not provided)
* @property initials - Custom initials to display when no image is available (optional, will be generated from displayName)
* @property displayName - Used for alt text and generating initials (required)
*/
export interface AvatarData {
src?: string;
color?: string;
initials?: string;
displayName: string;
}
/**
* Generates a deterministic color based on text
* @param text - The text to generate a color from
* @returns A Tailwind CSS color class
*/
const getRandomColor = (text: string): string => {
const colors = [
'bg-blue-500',
'bg-purple-500',
'bg-green-500',
'bg-orange-500',
'bg-red-500',
'bg-pink-500',
'bg-indigo-500',
'bg-yellow-500',
'bg-teal-500',
'bg-cyan-500',
'bg-emerald-500',
'bg-violet-500',
'bg-amber-500',
'bg-rose-500',
'bg-fuchsia-500',
'bg-sky-500',
];
// Generate a deterministic hash from the text
let hash = 0;
for (let i = 0; i < text.length; i++) {
hash = ((hash << 5) - hash + (text.codePointAt(i) ?? 0)) & 0xffffffff;
}
const colorIndex = Math.abs(hash) % colors.length;
return colors[colorIndex] || 'bg-gray-500';
};
/**
* Recommended image dimensions: 256x256 pixels
* Supported formats: JPG, PNG, WebP, SVG
* Maximum file size: 5MB
*/
export interface AvatarProps {
/**
* URL to the avatar image
*/
src?: string;
/**
* Alternative text for the avatar image, also used for generating initials if needed
*/
alt?: string;
/**
* Background color for the avatar when no image is provided
* Uses Tailwind CSS color classes (e.g., 'bg-blue-500')
* If not provided, a color will be generated based on the alt text
*/
color?: string;
/**
* Size of the avatar
* - sm: 32px (2rem)
* - md: 40px (2.5rem) - default
* - lg: 48px (3rem)
* - xl: 64px (4rem)
*/
size?: 'sm' | 'md' | 'lg' | 'xl';
/**
* Custom initials to display when no image is available
* If not provided, initials will be generated from the alt text
*/
initials?: string;
/**
* Click handler for the avatar, e.g for editing or viewing profiles
*/
onClick?: () => void;
}
/**
* Avatar component displays a user or room avatar with fallback to initials
*
* TODO: Consider breaking this component into smaller subcomponents:
* - AvatarImage: Handles image loading and error states
* - AvatarInitials: Handles initials generation and display
* - AvatarContainer: Handles sizing and common styling
*
* TODO:
* - Status indicators (online/offline/away)
* - Avatar groups/stacks for multiple users
* - Upload functionality for editable avatars
* - Image optimization and lazy loading
*
* @example
* // Basic usage
*