import React, { useState, useCallback, useEffect } from 'react'; import { FiX, FiRefreshCw, FiAlertTriangle, FiUser, FiHash, FiCopy, FiExternalLink, FiLink, FiStar, FiCpu, FiCamera, FiMic, FiFilm, FiCode, FiGlobe, FiBarChart2, FiDatabase, FiShare2, FiTrendingUp, FiActivity, FiShield, FiCheckCircle, FiAlertTriangle as FiAlert, FiBriefcase, FiLock, FiUsers, FiZap, } from 'react-icons/fi'; import { FaTwitter, FaGithub, FaGlobe, FaDiscord } from 'react-icons/fa'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from './ui/dialog'; import { Button } from './ui/Button'; import { Badge } from './ui/badge'; import Typography from './ui/Typography'; import { toast } from 'sonner'; import { gradients } from '../lib/styles'; import { useHRLImageUrl } from '../hooks/useHRLImageUrl'; import { NetworkType } from '@hashgraphonline/standards-sdk'; interface ProfileModalProps { agent: AgentProfile | null; isOpen: boolean; onClose: () => void; onConnect: (accountId: string) => void; } interface AgentProfile { id?: string; accountId: string; profile?: any; metadata?: any; rating?: number; ratingCount?: number; network?: string; createdAt?: string | Date; } interface SocialLink { platform: string; url?: string; handle?: string; } const capabilityIconMap: { [key: number]: { icon: React.ComponentType<{ className?: string }>; description: string; }; } = { 0: { icon: FiCpu, description: 'Text Generation' }, 1: { icon: FiCamera, description: 'Image Generation' }, 2: { icon: FiMic, description: 'Audio Generation' }, 3: { icon: FiFilm, description: 'Video Generation' }, 4: { icon: FiCode, description: 'Code Generation' }, 5: { icon: FiGlobe, description: 'Language Translation' }, 6: { icon: FiBarChart2, description: 'Summarization & Content Extraction' }, 7: { icon: FiDatabase, description: 'Knowledge Retrieval & Reasoning' }, 8: { icon: FiShare2, description: 'Data Integration & Visualization' }, 9: { icon: FiTrendingUp, description: 'Market Intelligence' }, 10: { icon: FiActivity, description: 'Transaction Analytics' }, 11: { icon: FiShield, description: 'Smart Contract Audit' }, 12: { icon: FiCheckCircle, description: 'Governance Facilitation' }, 13: { icon: FiAlert, description: 'Security Monitoring' }, 14: { icon: FiBriefcase, description: 'Compliance & Regulatory Analysis' }, 15: { icon: FiLock, description: 'Fraud Detection & Prevention' }, 16: { icon: FiUsers, description: 'Multi-Agent Coordination' }, 17: { icon: FiLink, description: 'API Integration & Orchestration' }, 18: { icon: FiZap, description: 'Workflow Automation' }, }; /** * Component for displaying a field with copy functionality */ const MetadataField: React.FC<{ label: string; value: string; icon?: React.ReactNode; copyButton?: boolean; externalLink?: string; }> = ({ label, value, icon, copyButton = true, externalLink }) => { const [copied, setCopied] = useState(false); const handleCopy = useCallback(async () => { try { await navigator.clipboard.writeText(value); setCopied(true); toast.success('Copied to clipboard'); setTimeout(() => setCopied(false), 2000); } catch (error) { toast.error('Failed to copy'); } }, [value]); return (
{icon ?
{icon}
: null}
{label} {value}
{externalLink && ( )} {copyButton && ( )}
); }; /** * Agent Profile Modal component */ export const AgentProfileModal: React.FC = ({ agent, isOpen, onClose, onConnect, }) => { const [isLoading, setIsLoading] = useState(false); const [profileData, setProfileData] = useState(null); const agentData = agent || null; const { metadata, accountId } = agentData || {}; const { name, description, logo, profileImage, socials, bio, display_name, alias, aiAgent, inboundTopicId, } = metadata || {}; const displayName = display_name || alias || name || 'Unknown Agent'; const rawAvatarUrl = profileImage || logo; const capabilities = aiAgent?.capabilities || []; const rating = agentData?.rating || 0; const ratingCount = agentData?.ratingCount || 0; const network = agentData?.network === 'testnet' ? 'testnet' : 'mainnet'; const { resolvedUrl: avatarUrl, isLoading: imageLoading, error: imageError } = useHRLImageUrl( rawAvatarUrl || '', network as NetworkType ); const fetchFullProfile = useCallback(async () => { if (!agentData?.accountId) return; setIsLoading(true); try { const result = await window.electron.invoke('hcs10:get-agent-profile', { accountId: agentData.accountId, }); if (result.success) { setProfileData(result.data); } else { toast.error('Failed to load full profile'); } } catch (error) { toast.error('Error loading profile'); } finally { setIsLoading(false); } }, [agentData?.accountId]); useEffect(() => { if (isOpen && agentData) { fetchFullProfile(); } }, [isOpen, agentData, fetchFullProfile]); if (!agentData) return null; const SocialsSection = () => { if (!socials) return null; const socialLinks = Array.isArray(socials) ? socials : [socials]; return (
{socialLinks.map((social: SocialLink, index: number) => { let icon = ; let url = social.url || social.handle; if (!url) return null; if (social.platform === 'twitter' || social.platform === 'x') { icon = ; if (!url.includes('http')) { url = `https://twitter.com/${url.replace('@', '')}`; } } else if (social.platform === 'github') { icon = ; if (!url.includes('http')) { url = `https://github.com/${url}`; } } else if (social.platform === 'discord') { icon = ; } return ( ); })}
); }; const CapabilitiesSection = () => { if (!capabilities.length) return null; return (
Capabilities
{capabilities.map((capabilityId: number) => { const capabilityInfo = capabilityIconMap[capabilityId]; const IconComponent = capabilityInfo?.icon || FiUser; const description = capabilityInfo?.description || `Capability ${capabilityId}`; return ( {description} ); })}
); }; return ( Agent Profile
{imageLoading ? ( ) : avatarUrl ? ( {`${displayName} { }} /> ) : ( {displayName.charAt(0)} )}
{imageError && (
)}
{displayName} {rating > 0 && (
{rating.toFixed(1)} ({ratingCount} reviews)
{network}
)} {(description || bio) && ( {description || bio} )}
} externalLink={`https://hashscan.io/${agent?.network === 'testnet' ? 'testnet/' : ''}account/${accountId}`} /> {inboundTopicId && ( } externalLink={`https://hashscan.io/${agent?.network === 'testnet' ? 'testnet/' : ''}topic/${inboundTopicId}`} /> )} {profileData?.outboundTopicId && ( } externalLink={`https://hashscan.io/${agent?.network === 'testnet' ? 'testnet/' : ''}topic/${profileData.outboundTopicId}`} /> )} {aiAgent?.creator && ( } copyButton={false} /> )}
{isLoading && (
Loading additional profile data...
)}
); }; export default AgentProfileModal;