core/apps/webapp/app/components/integrations/api-key-auth-section.tsx
Harshith Mullapudi 038acea669
Feat: added integration connect and mcp oAuth (#20)
* Feat: added integration connect and mcp oAuth

* Feat: add mcp support to chat

* Fix: UI for integrations and logs

* Fix: ui

* Fix: proxy server

* Feat: enhance MCP tool integration and loading functionality

* Fix: added header

* Fix: Linear integration sync

---------

Co-authored-by: Manoj K <saimanoj58@gmail.com>
2025-07-17 12:41:32 +05:30

109 lines
3.0 KiB
TypeScript

import React, { useState, useCallback } from "react";
import { useFetcher } from "@remix-run/react";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
interface ApiKeyAuthSectionProps {
integration: {
id: string;
name: string;
};
specData: any;
activeAccount: any;
}
export function ApiKeyAuthSection({
integration,
specData,
activeAccount,
}: ApiKeyAuthSectionProps) {
const [apiKey, setApiKey] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [showApiKeyForm, setShowApiKeyForm] = useState(false);
const apiKeyFetcher = useFetcher();
const handleApiKeyConnect = useCallback(() => {
if (!apiKey.trim()) return;
setIsLoading(true);
apiKeyFetcher.submit(
{
integrationDefinitionId: integration.id,
apiKey,
},
{
method: "post",
action: "/api/v1/integration_account",
encType: "application/json",
},
);
}, [integration.id, apiKey, apiKeyFetcher]);
React.useEffect(() => {
if (apiKeyFetcher.state === "idle" && isLoading) {
if (apiKeyFetcher.data !== undefined) {
window.location.reload();
}
}
}, [apiKeyFetcher.state, apiKeyFetcher.data, isLoading]);
if (activeAccount || !specData?.auth?.api_key) {
return null;
}
return (
<div className="bg-background-3 space-y-4 rounded-lg p-4">
<h4 className="font-medium">API Key Authentication</h4>
{!showApiKeyForm ? (
<Button
variant="secondary"
onClick={() => setShowApiKeyForm(true)}
className="w-full"
>
Connect with API Key
</Button>
) : (
<div className="space-y-3">
<div className="space-y-2">
<label htmlFor="apiKey" className="text-sm font-medium">
{specData?.auth?.api_key?.label || "API Key"}
</label>
<Input
id="apiKey"
placeholder="Enter your API key"
value={apiKey}
onChange={(e) => setApiKey(e.target.value)}
/>
{specData?.auth?.api_key?.description && (
<p className="text-muted-foreground text-xs">
{specData.auth.api_key.description}
</p>
)}
</div>
<div className="flex justify-end gap-2">
<Button
type="button"
variant="ghost"
onClick={() => {
setShowApiKeyForm(false);
setApiKey("");
}}
>
Cancel
</Button>
<Button
type="button"
variant="default"
disabled={isLoading || !apiKey.trim()}
onClick={handleApiKeyConnect}
>
{isLoading || apiKeyFetcher.state === "submitting"
? "Connecting..."
: "Connect"}
</Button>
</div>
</div>
)}
</div>
);
}