'use client'; import { useState, useMemo } from 'react'; import { YieldPool } from '@/types'; import { SecurityBadge } from './SecurityScore'; import { formatNumber, formatPercent, getSecurityRating, getRatingColor } from '@/utils/security'; import { ExternalLink, ChevronDown, ChevronUp, ArrowUpDown, Shield, TrendingUp, Wallet, Info } from 'lucide-react'; interface PoolsTableProps { pools: YieldPool[]; isLoading?: boolean; } type SortField = 'apy' | 'tvl' | 'securityScore' | 'protocol'; type SortDirection = 'asc' | 'desc'; export function PoolsTable({ pools, isLoading }: PoolsTableProps) { const [sortField, setSortField] = useState('apy'); const [sortDirection, setSortDirection] = useState('desc'); const [expandedRow, setExpandedRow] = useState(null); const sortedPools = useMemo(() => { return [...pools].sort((a, b) => { let comparison = 0; switch (sortField) { case 'apy': comparison = a.apy - b.apy; break; case 'tvl': comparison = a.tvl - b.tvl; break; case 'securityScore': comparison = a.securityScore - b.securityScore; break; case 'protocol': comparison = a.protocol.localeCompare(b.protocol); break; } return sortDirection === 'desc' ? -comparison : comparison; }); }, [pools, sortField, sortDirection]); const handleSort = (field: SortField) => { if (field === sortField) { setSortDirection(prev => prev === 'desc' ? 'asc' : 'desc'); } else { setSortField(field); setSortDirection('desc'); } }; const SortIcon = ({ field }: { field: SortField }) => { if (field !== sortField) { return ; } return sortDirection === 'desc' ? : ; }; if (isLoading) { return ; } if (pools.length === 0) { return (
Aucun pool trouvé
Essayez de modifier vos filtres
); } return (
{/* Header */}

Tous les pools ({pools.length})

{/* Table */}
{sortedPools.map((pool) => ( setExpandedRow( expandedRow === pool.id ? null : pool.id )} /> ))}
Asset Réseau Action
); } // Row component interface PoolRowProps { pool: YieldPool; isExpanded: boolean; onToggleExpand: () => void; } function PoolRow({ pool, isExpanded, onToggleExpand }: PoolRowProps) { const securityColor = getRatingColor(getSecurityRating(pool.securityScore)); const exploitCount = pool.exploits || 0; return ( <> {/* Protocol */}
{pool.protocolLogo ? ( {pool.protocol} { (e.target as HTMLImageElement).style.display = 'none'; (e.target as HTMLImageElement).nextElementSibling?.classList.remove('hidden'); }} /> ) : null}
{pool.protocol.charAt(0)}
{pool.protocol} {pool.protocolType && ( {pool.protocolType === 'lending' ? 'Lending' : 'Vault'} )}
{/* Asset with logo */}
{pool.stablecoinLogo ? ( {pool.stablecoin} { (e.target as HTMLImageElement).style.display = 'none'; }} /> ) : null} {pool.stablecoin} {/* Indicateur USD/EUR */} {pool.currency}
{/* Chain with logo */}
{pool.chainLogo ? ( {pool.chain} { (e.target as HTMLImageElement).style.display = 'none'; }} /> ) : null} {pool.chain}
{/* APY */}
{formatPercent(pool.apy)}
{pool.apyReward > 0 && (
Base {formatPercent(pool.apyBase)} + {formatPercent(pool.apyReward)}
)} {/* TVL */}
{formatNumber(pool.tvl)}
{/* Security with exploit indicator */}
{exploitCount >= 2 && ( ⚠ {exploitCount} exploits )} {exploitCount === 1 && ( 1 exploit )}
{/* Action */} Déposer {/* Expanded details */} {isExpanded && (
Audits
{pool.audits} audit{pool.audits > 1 ? 's' : ''}
Ancienneté
{pool.protocolAge > 365 ? `${Math.floor(pool.protocolAge / 365)} an${Math.floor(pool.protocolAge / 365) > 1 ? 's' : ''}` : `${pool.protocolAge} jours` }
Historique exploits
= 2 ? 'text-red-400' : 'text-yellow-400' }`}> {exploitCount === 0 ? '✓ Aucun exploit' : `⚠ ${exploitCount} exploit${exploitCount > 1 ? 's' : ''}` }
Type
{pool.protocolType === 'lending' ? 'Protocole de prêt' : 'Gestionnaire de vault'}
)} ); } // Loading skeleton function PoolsTableSkeleton() { return (
{[...Array(5)].map((_, i) => (
))}
); }