import { Bot, Users, BarChart3, Trash2, Pencil, Eye, EyeOff, Copy, Check, } from 'lucide-react' import type { TraderInfo, Exchange } from '../../types' import type { Language } from '../../i18n/translations' import { t } from '../../i18n/translations' import { PunkAvatar, getTraderAvatar } from '../common/PunkAvatar' import { getModelDisplayName, getExchangeDisplayName, isPerpDexExchange, getWalletAddress, truncateAddress, } from './model-constants' interface TradersListProps { traders: TraderInfo[] | undefined isLoading: boolean allExchanges: Exchange[] configuredModelsCount: number configuredExchangesCount: number visibleTraderAddresses: Set copiedId: string | null language: Language onTraderSelect?: (traderId: string) => void onNavigate: (path: string) => void onEditTrader: (traderId: string) => void onToggleTrader: (traderId: string, running: boolean) => void onToggleCompetition: (traderId: string, currentShowInCompetition: boolean) => void onDeleteTrader: (traderId: string) => void onToggleTraderAddress: (traderId: string) => void onCopyAddress: (id: string, address: string) => void } export function TradersList({ traders, isLoading, allExchanges, configuredModelsCount, configuredExchangesCount, visibleTraderAddresses, copiedId, language, onTraderSelect, onNavigate, onEditTrader, onToggleTrader, onToggleCompetition, onDeleteTrader, onToggleTraderAddress, onCopyAddress, }: TradersListProps) { return (

{t('currentTraders', language)}

{isLoading ? ( ) : traders && traders.length > 0 ? (
{traders.map((trader) => ( ))}
) : ( )}
) } function TradersLoadingSkeleton() { return (
{[1, 2, 3].map((i) => (
))}
) } function TradersEmptyState({ configuredModelsCount, configuredExchangesCount, language, }: { configuredModelsCount: number configuredExchangesCount: number language: Language }) { return (
{t('noTraders', language)}
{t('createFirstTrader', language)}
{(configuredModelsCount === 0 || configuredExchangesCount === 0) && (
{configuredModelsCount === 0 && configuredExchangesCount === 0 ? t('configureModelsAndExchangesFirst', language) : configuredModelsCount === 0 ? t('configureModelsFirst', language) : t('configureExchangesFirst', language)}
)}
) } function TraderRow({ trader, allExchanges, visibleTraderAddresses, copiedId, language, onTraderSelect, onNavigate, onEditTrader, onToggleTrader, onToggleCompetition, onDeleteTrader, onToggleTraderAddress, onCopyAddress, }: { trader: TraderInfo allExchanges: Exchange[] visibleTraderAddresses: Set copiedId: string | null language: Language onTraderSelect?: (traderId: string) => void onNavigate: (path: string) => void onEditTrader: (traderId: string) => void onToggleTrader: (traderId: string, running: boolean) => void onToggleCompetition: (traderId: string, currentShowInCompetition: boolean) => void onDeleteTrader: (traderId: string) => void onToggleTraderAddress: (traderId: string) => void onCopyAddress: (id: string, address: string) => void }) { const exchange = allExchanges.find(e => e.id === trader.exchange_id) const walletAddr = getWalletAddress(exchange) const isPerpDex = isPerpDexExchange(exchange?.exchange_type) const isVisible = visibleTraderAddresses.has(trader.trader_id) const isCopied = copiedId === trader.trader_id return (
{trader.trader_name}
{getModelDisplayName( trader.ai_model.split('_').pop() || trader.ai_model )}{' '} Model • {getExchangeDisplayName(trader.exchange_id, allExchanges)}
{/* Wallet Address for Perp-DEX */} {isPerpDex && walletAddr && (
{isVisible ? walletAddr : truncateAddress(walletAddr)}
)} {/* Status */}
{trader.is_running ? t('running', language) : t('stopped', language)}
{/* Actions */}
) }