// components/ApiKeyForm.tsx
export function ApiKeyForm({
tool,
userId,
onSuccess,
}: {
tool: Tool;
userId: string;
onSuccess: () => void;
}) {
const [credentialName, setCredentialName] = useState("");
const [keyValues, setKeyValues] = useState<Record<string, string>>({});
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// Derive field names from the tool's form definition
// For no_auth tools, fields will be empty
const fields = tool.auth_type === "api_key"
? Object.keys(tool.form ?? { api_key: {} })
: [];
async function handleSubmit() {
setLoading(true);
setError(null);
try {
await createStaticCredential({
tool,
userId,
credentialName,
apiKeyValues: keyValues,
});
onSuccess();
} catch (e: any) {
setError(e.message);
} finally {
setLoading(false);
}
}
return (
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-1">Connection Name</label>
<input
className="w-full border rounded px-3 py-2"
placeholder="e.g. My Brave Search"
value={credentialName}
onChange={(e) => setCredentialName(e.target.value)}
/>
</div>
{fields.map((field) => (
<div key={field}>
<label className="block text-sm font-medium mb-1 capitalize">
{field.replace(/_/g, " ")}
</label>
<input
type="password"
className="w-full border rounded px-3 py-2 font-mono"
placeholder={`Enter ${field}`}
value={keyValues[field] ?? ""}
onChange={(e) =>
setKeyValues((prev) => ({ ...prev, [field]: e.target.value }))
}
/>
</div>
))}
{error && <p className="text-red-500 text-sm">{error}</p>}
<button
onClick={handleSubmit}
disabled={loading || !credentialName}
className="w-full bg-blue-600 text-white rounded px-4 py-2 disabled:opacity-50"
>
{loading ? "Connecting..." : tool.auth_type === "no_auth" ? "Enable Tool" : "Connect"}
</button>
</div>
);
}