import { useState } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { secretsApi } from "@/api/secrets"; import { puterProxyApi } from "@/api/puter-proxy"; import { useCompany } from "@/context/CompanyContext"; import { useToast } from "@/context/ToastContext"; import { queryKeys } from "@/lib/queryKeys"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { SettingsSection, SettingsRow } from "./SettingsSection"; const PROVIDERS: ReadonlyArray<{ id: "anthropic" | "openai"; label: string }> = [ { id: "anthropic", label: "Anthropic API key" }, { id: "openai", label: "OpenAI API key" }, ]; interface ProviderRowProps { id: "anthropic" | "openai"; label: string; hasKey: boolean; companyId: string | null; } function ProviderRow({ id, label, hasKey, companyId }: ProviderRowProps) { const [editing, setEditing] = useState(false); const [value, setValue] = useState(""); const queryClient = useQueryClient(); const { pushToast } = useToast(); const saveMutation = useMutation({ mutationFn: async (apiKey: string) => { if (!companyId) throw new Error("No workspace selected"); if (!apiKey.trim()) throw new Error("API key cannot be empty"); await puterProxyApi.storeApiKey(companyId, id, apiKey.trim()); }, onSuccess: async () => { setEditing(false); setValue(""); pushToast({ tone: "success", title: `${label} saved.` }); if (companyId) { await queryClient.invalidateQueries({ queryKey: queryKeys.secrets.list(companyId), }); } }, onError: (error) => { pushToast({ tone: "error", title: error instanceof Error ? error.message : `Failed to save ${label}.`, }); }, }); if (editing) { return (
{ e.preventDefault(); saveMutation.mutate(value); }} > setValue(e.target.value)} placeholder="sk-..." autoComplete="off" aria-label={`${label} input`} className="h-8 w-56 text-xs focus-visible:ring-offset-background" />
); } return (
{hasKey ? "set" : "not set"}
); } export function CloudProvidersSection() { const { selectedCompanyId } = useCompany(); const secretsQuery = useQuery({ queryKey: selectedCompanyId ? queryKeys.secrets.list(selectedCompanyId) : ["secrets", "none"], queryFn: () => (selectedCompanyId ? secretsApi.list(selectedCompanyId) : Promise.resolve([])), enabled: Boolean(selectedCompanyId), }); const secretNames = new Set( (secretsQuery.data ?? []).map((s) => s.name.toLowerCase()), ); return ( {PROVIDERS.map((provider) => ( ))} Enabled {!selectedCompanyId ? (
Select a workspace to configure API keys.
) : null}
); }