import React, { useState } from 'react'; import { Edit2, Trash2, Power, Globe } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { ProxyEntry } from '../../../types/config'; import ProxyEditModal from './ProxyEditModal'; import { Account } from '../../../types/account'; interface ProxyListProps { proxies: ProxyEntry[]; onUpdate: (proxies: ProxyEntry[]) => void; accountBindings: Record; accounts: Account[]; selectedIds: Set; onSelectionChange: (ids: Set) => void; isTesting?: boolean; } export default function ProxyList({ proxies, onUpdate, accountBindings, accounts, selectedIds, onSelectionChange, isTesting }: ProxyListProps) { const { t } = useTranslation(); const [editingProxy, setEditingProxy] = useState(undefined); const [isEditModalOpen, setIsEditModalOpen] = useState(false); const handleEdit = (proxy: ProxyEntry) => { setEditingProxy(proxy); setIsEditModalOpen(true); }; const handleDelete = (id: string) => { if (confirm(t('settings.proxy_pool.confirm_delete', 'Are you sure you want to delete this proxy?'))) { onUpdate(proxies.filter(p => p.id !== id)); } }; const handleSaveProxy = (entry: ProxyEntry) => { if (editingProxy) { onUpdate(proxies.map(p => p.id === entry.id ? entry : p)); } setEditingProxy(undefined); }; const handleToggleEnabled = (id: string) => { onUpdate(proxies.map(p => p.id === id ? { ...p, enabled: !p.enabled } : p)); }; const sortedProxies = [...proxies].sort((a, b) => a.priority - b.priority); const handleSelectAll = (e: React.ChangeEvent) => { if (e.target.checked) { onSelectionChange(new Set(proxies.map(p => p.id))); } else { onSelectionChange(new Set()); } }; const handleSelectOne = (id: string) => { const newSelected = new Set(selectedIds); if (newSelected.has(id)) { newSelected.delete(id); } else { newSelected.add(id); } onSelectionChange(newSelected); }; const isAllSelected = proxies.length > 0 && selectedIds.size === proxies.length; const isSomeSelected = selectedIds.size > 0 && selectedIds.size < proxies.length; // Helper to get bound accounts for a proxy const getBoundAccounts = (proxyId: string) => { const boundAccountIds = Object.entries(accountBindings) .filter(([_, boundProxyId]) => boundProxyId === proxyId) .map(([accountId]) => accountId); return boundAccountIds.map(id => accounts.find(a => a.id === id)).filter(Boolean) as Account[]; }; return (
{sortedProxies.length === 0 ? ( ) : ( sortedProxies.map((proxy) => { const boundAccounts = getBoundAccounts(proxy.id); return ( ) }) )}
{ if (input) input.indeterminate = isSomeSelected; }} onChange={handleSelectAll} className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" /> {t('settings.proxy_pool.column_priority', 'PRI')} {t('settings.proxy_pool.column_status', 'Status')} {t('settings.proxy_pool.column_details', 'Proxy Details')} {t('settings.proxy_pool.column_bindings', 'Bindings')} {t('common.actions', 'Actions')}
{t('settings.proxy_pool.empty', 'No proxies available.')}
handleSelectOne(proxy.id)} className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" />
{proxy.priority}
{/* Status Pill Tag */}
{!proxy.enabled ? t('settings.proxy_pool.status.inactive', 'Inactive') : proxy.latency !== undefined && proxy.latency !== null ? `${proxy.latency}ms` : isTesting ? t('settings.proxy_pool.status.checking', 'Checking') : proxy.is_healthy ? t('settings.proxy_pool.status.healthy', 'Healthy') : t('settings.proxy_pool.status.timeout', 'Timeout') }
{proxy.name} {proxy.tags.map(tag => ( {tag} ))}
{proxy.url}
{boundAccounts.length > 0 ? (
a.email).join('\n')}`}> {boundAccounts.slice(0, 2).map(acc => (
{acc.email.split('@')[0].substring(0, 4)}
))} {boundAccounts.length > 2 && (
+{boundAccounts.length - 2}
)}
) : ( {t('common.none', 'None')} )}
{isEditModalOpen && editingProxy && ( setIsEditModalOpen(false)} onSave={handleSaveProxy} initialData={editingProxy} isEditing={true} /> )}
); }