Files
fusion/packages/dashboard/app/components/AgentAvatar.tsx
Fusion 964e111f8b feat(FN-3118): document avatar storage in agents and architecture
Added avatar storage and field documentation to the agents guide, with a minor reference added to the architecture docs.

Fusion-Task-Id: FN-3118
2026-05-05 20:47:37 -07:00

51 lines
1.4 KiB
TypeScript

import { Bot } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import "./AgentAvatar.css";
interface AgentAvatarProps {
agent: {
id: string;
icon?: string;
imageUrl?: string;
name: string;
updatedAt?: string;
};
size?: number;
className?: string;
}
export function AgentAvatar({ agent, size = 36, className }: AgentAvatarProps) {
const [imageError, setImageError] = useState(false);
useEffect(() => {
setImageError(false);
}, [agent.imageUrl]);
const imageSrc = useMemo(() => {
if (!agent.imageUrl) return undefined;
const timestamp = encodeURIComponent(agent.updatedAt ?? "");
const joiner = agent.imageUrl.includes("?") ? "&" : "?";
return `${agent.imageUrl}${joiner}t=${timestamp}`;
}, [agent.imageUrl, agent.updatedAt]);
return (
<span
className={`agent-avatar${className ? ` ${className}` : ""}`}
style={{ width: `${size}px`, height: `${size}px` }}
aria-label={`${agent.name} avatar`}
>
{imageSrc && !imageError ? (
<img src={imageSrc} alt={`${agent.name} avatar`} onError={() => setImageError(true)} />
) : agent.icon?.trim() ? (
<span className="agent-avatar-emoji" style={{ fontSize: `calc(${size}px * 0.58)` }} aria-hidden="true">
{agent.icon}
</span>
) : (
<Bot size={Math.max(14, Math.round(size * 0.55))} aria-hidden="true" />
)}
</span>
);
}
export type { AgentAvatarProps };