import { useState, useCallback, useEffect } from "preact/hooks"; import { useI18n, useT } from "../../../shared/i18n/context"; import { AccountCard } from "./AccountCard"; import { AccountImportExport } from "./AccountImportExport"; import type { Account, ProxyEntry, QuotaWarning } from "../../../shared/types"; interface AccountListProps { accounts: Account[]; loading: boolean; onDelete: (id: string) => Promise; onRefresh: () => void; refreshing: boolean; lastUpdated: Date | null; proxies?: ProxyEntry[]; onProxyChange?: (accountId: string, proxyId: string) => void; onExport?: (selectedIds?: string[]) => Promise; onImport?: (file: File) => Promise<{ success: boolean; added: number; updated: number; failed: number; errors: string[] }>; } export function AccountList({ accounts, loading, onDelete, onRefresh, refreshing, lastUpdated, proxies, onProxyChange, onExport, onImport }: AccountListProps) { const t = useT(); const { lang } = useI18n(); const [selectedIds, setSelectedIds] = useState>(new Set()); const [warnings, setWarnings] = useState([]); // Poll quota warnings useEffect(() => { const fetchWarnings = async () => { try { const resp = await fetch("/auth/quota/warnings"); const data = await resp.json(); setWarnings(data.warnings || []); } catch { /* ignore */ } }; fetchWarnings(); const timer = setInterval(fetchWarnings, 30_000); return () => clearInterval(timer); }, []); const toggleSelect = useCallback((id: string) => { setSelectedIds((prev) => { const next = new Set(prev); if (next.has(id)) next.delete(id); else next.add(id); return next; }); }, []); const toggleSelectAll = useCallback(() => { setSelectedIds((prev) => { if (prev.size === accounts.length) return new Set(); return new Set(accounts.map((a) => a.id)); }); }, [accounts]); const updatedAtText = lastUpdated ? lastUpdated.toLocaleTimeString(lang === "zh" ? "zh-CN" : "en-US", { hour: "2-digit", minute: "2-digit", second: "2-digit" }) : null; return (

{t("connectedAccounts")}

{t("connectedAccountsDesc")}

{updatedAtText && ( )} {t("manageAccounts")} → {t("usageStats")} → {onExport && onImport && ( )} {accounts.length > 0 && ( )}
{/* Quota warning banners */} {warnings.filter((w) => w.level === "critical").length > 0 && (
{t("quotaCriticalWarning").replace("{count}", String(warnings.filter((w) => w.level === "critical").length))}
)} {warnings.filter((w) => w.level === "warning").length > 0 && warnings.filter((w) => w.level === "critical").length === 0 && (
{t("quotaWarning").replace("{count}", String(warnings.filter((w) => w.level === "warning").length))}
)}
{loading ? (
{t("loadingAccounts")}
) : accounts.length === 0 ? (
{t("noAccounts")}
) : ( accounts.map((acct, i) => ( )) )}
); }