import { useState } from "preact/hooks"; import { useT } from "../../../shared/i18n/context"; import type { AssignmentAccount } from "../../../shared/hooks/use-proxy-assignments"; import type { ProxyEntry } from "../../../shared/types"; interface ProxyGroup { id: string; label: string; count: number; } interface ProxyGroupListProps { accounts: AssignmentAccount[]; proxies: ProxyEntry[]; selectedGroup: string | null; onSelectGroup: (groupId: string | null) => void; } export function ProxyGroupList({ accounts, proxies, selectedGroup, onSelectGroup }: ProxyGroupListProps) { const t = useT(); const [search, setSearch] = useState(""); // Build groups with counts const groups: ProxyGroup[] = []; // "All" groups.push({ id: "__all__", label: t("allAccounts"), count: accounts.length }); // Count by assignment const countMap = new Map(); for (const acct of accounts) { const key = acct.proxyId || "global"; countMap.set(key, (countMap.get(key) || 0) + 1); } // Special groups groups.push({ id: "global", label: t("globalDefault"), count: countMap.get("global") || 0 }); // Proxy entries for (const p of proxies) { groups.push({ id: p.id, label: p.name, count: countMap.get(p.id) || 0 }); } groups.push({ id: "direct", label: t("directNoProxy"), count: countMap.get("direct") || 0 }); groups.push({ id: "auto", label: t("autoRoundRobin"), count: countMap.get("auto") || 0 }); // "Unassigned" — accounts not in any explicit assignment (they default to "global") // Since getAssignment defaults to "global", all accounts have a proxyId. // "Unassigned" is not really a separate bucket in this model — skip or show 0. const lowerSearch = search.toLowerCase(); const filtered = search ? groups.filter((g) => g.label.toLowerCase().includes(lowerSearch)) : groups; const active = selectedGroup ?? "__all__"; return (
{/* Search */} setSearch((e.target as HTMLInputElement).value)} class="px-3 py-2 text-sm border border-gray-200 dark:border-border-dark rounded-lg bg-white dark:bg-bg-dark text-slate-700 dark:text-text-main focus:outline-none focus:ring-1 focus:ring-primary mb-2" /> {filtered.map((g) => { const isActive = active === g.id; return ( ); })}
); }