/** * @file PoolAccountSettings — Settings → AI tools → Pool account: in server * mode, every user picks which account of the shared account pool their own * new sessions run on, per tool, among the accounts their pool group may use * (`GET/PUT /api/me/pool-accounts`, server/lib/account-pins.js `setChoice`). * "Automatic" leaves it to the balancer; an admin's pin locks the choice. A * Claude login goes into the user's home at once, so running panes follow it; * Codex and Cursor take it at the next session. Renders nothing in local mode * or when the pool holds no account the user may use. * @author Nguyễn Ngọc Trí Vĩ */ import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Lock } from "lucide-react"; import { api, type MyPoolTool, type PoolTool } from "../../lib/api"; import { toast } from "../../lib/toast"; import { usePermissions } from "../AuthGate"; import { AiToolIcon } from "../AiToolIcon"; import { SettingsRow, SettingsSection } from "./SettingsRow"; const LABEL: Record = { claude: "Claude Code", codex: "Codex", cursor: "Cursor" }; export function PoolAccountSettings() { const { t } = useTranslation("settings"); const { local } = usePermissions(); const [tools, setTools] = useState(null); const [busy, setBusy] = useState(null); useEffect(() => { if (local) return; api.me .poolAccounts() .then((r) => setTools(r.tools)) .catch(() => setTools(null)); }, [local]); if (local || !tools?.length) return null; const choose = async (tool: PoolTool, account: string | null) => { setBusy(tool); try { const r = await api.me.choosePoolAccount(tool, account); setTools((list) => (list ?? []).map((x) => (x.tool === tool ? { ...x, choice: r.choice } : x)) ); toast.success( !r.choice ? t("poolAccount.automaticSaved") : r.switched === "switched" || r.switched === "kept" ? t("poolAccount.switchedNow", { account: r.choice }) : t("poolAccount.nextSession", { account: r.choice }) ); } catch (err) { toast.error(err); } finally { setBusy(null); } }; return ( {tools.map((x) => ( {LABEL[x.tool]} } description={ x.pin ? ( {t("poolAccount.pinned", { account: x.pin })} ) : ( t("poolAccount.count", { count: x.accounts.length }) ) } disabled={!!x.pin} control={ } /> ))} ); }