"use client"; import { useState, useEffect, useRef } from "react"; import { normalizeAvatarUrl } from "@/lib/avatars"; interface AvatarProps { src: string | null | undefined; username: string; size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl"; className?: string; borderClassName?: string; fallbackText?: string; style?: React.CSSProperties; } const sizeClasses = { xs: "w-6 h-6 text-[8px]", sm: "w-8 h-8 text-[10px]", md: "w-10 h-10 text-xs", lg: "w-16 h-16 sm:w-20 sm:h-20 text-xl sm:text-2xl", xl: "w-24 h-24 text-4xl", "2xl": "w-32 h-32 text-4xl", }; export default function Avatar({ src, username, size = "md", className = "", borderClassName = "", fallbackText, style, }: AvatarProps) { const [avatarError, setAvatarError] = useState(false); const prevSrcRef = useRef(undefined); // Reset error state when src changes useEffect(() => { if (src !== prevSrcRef.current) { prevSrcRef.current = src; // Reset error when src changes to allow retry // eslint-disable-next-line react-hooks/set-state-in-effect setAvatarError(false); } }, [src]); const sizeClass = sizeClasses[size]; const normalizedSrc = normalizeAvatarUrl(src); const displaySrc = normalizedSrc && !avatarError ? normalizedSrc : null; const initial = fallbackText || username.charAt(0).toUpperCase(); return (
{displaySrc ? ( {username} setAvatarError(true)} /> ) : null} {initial}
); }