This commit is contained in:
pradeepkumar
2026-03-27 15:47:29 +05:30
parent bed03ad949
commit 37d66150c3
9 changed files with 84 additions and 85 deletions

View File

@@ -82,33 +82,28 @@ function formatLastSeen(lastSeenAt: string | null | undefined, isOnline: boolean
return `Last seen ${diffDays}d ago`;
}
// Avatar component with shimmer loading animation
function AvatarWithPlaceholder({ src, alt, size }: { src: string; alt: string; size: number }) {
// Avatar component with shimmer loading animation and initials fallback
function AvatarWithPlaceholder({ src, alt, size, name }: { src: string; alt: string; size: number; name?: string }) {
const [loaded, setLoaded] = useState(false);
const [imgError, setImgError] = useState(false);
const placeholder = '/assets/icons/user-placeholder-icon.svg';
const isPlaceholder = !src || src === placeholder;
const initial = name?.[0]?.toUpperCase() || '?';
return (
<>
{(!src || !loaded) && (
<div className="absolute inset-0 rounded-full shimmer-loading" />
)}
{src && !isPlaceholder && (
{/* Initials base layer - always rendered behind image */}
<div className="absolute inset-0 rounded-full bg-[#c4d9d4] flex items-center justify-center">
<span className="font-bold text-[#00293d]" style={{ fontSize: size * 0.4 }}>{initial}</span>
</div>
{src && !isPlaceholder && !imgError && (
<img
ref={(el) => { if (el?.complete && el.naturalWidth > 0) setLoaded(true); }}
src={src}
alt={alt}
className={`absolute inset-0 w-full h-full object-cover transition-opacity duration-300 ${loaded ? 'opacity-100' : 'opacity-0'}`}
onLoad={() => setLoaded(true)}
/>
)}
{src && isPlaceholder && (
<Image
src={placeholder}
alt={alt}
width={size}
height={size}
className="absolute inset-0 w-full h-full object-cover"
onError={() => setImgError(true)}
/>
)}
</>
@@ -730,6 +725,7 @@ export function MessagingPage({ initialConversationId }: { initialConversationId
src={getValidAvatarUrl(agent.avatarUrl)}
alt={agent.name}
size={50}
name={agent.name}
/>
</div>
</div>
@@ -797,6 +793,7 @@ export function MessagingPage({ initialConversationId }: { initialConversationId
src={getValidAvatarUrl(conversationAvatarUrls[conversation.id])}
alt={conversation.otherParty?.name || 'User'}
size={70}
name={conversation.otherParty?.name}
/>
</div>
{conversation.otherParty?.isOnline && (