RosticFACE's picture
Upload 28 files
4840fb6 verified
import React from 'react';
import KeyIcon from './icons/KeyIcon';
import GoogleIcon from './icons/GoogleIcon';
import OpenAIIcon from './icons/OpenAIIcon';
import AnthropicIcon from './icons/AnthropicIcon';
import { Provider } from '../types';
interface ApiConfigProps {
provider: Provider;
setProvider: (provider: Provider) => void;
apiKeys: { gemini: string; openai: string; anthropic: string; };
setApiKey: (provider: Provider, key: string) => void;
isProcessing: boolean;
}
const ProviderTab: React.FC<{
providerName: Provider;
activeProvider: Provider;
setProvider: (provider: Provider) => void;
isProcessing: boolean;
children: React.ReactNode;
}> = ({ providerName, activeProvider, setProvider, isProcessing, children }) => {
const isActive = providerName === activeProvider;
const activeClasses = 'border-blue-400 text-white bg-gray-700/50';
const inactiveClasses = 'border-transparent text-gray-400 hover:bg-gray-700/30 hover:text-gray-200';
return (
<button
onClick={() => setProvider(providerName)}
disabled={isProcessing}
className={`flex-1 flex items-center justify-center gap-2 px-4 py-3 border-b-2 font-semibold transition-all duration-200 disabled:cursor-not-allowed disabled:opacity-60 ${isActive ? activeClasses : inactiveClasses}`}
role="tab"
aria-selected={isActive}
>
{children}
</button>
);
};
const ApiConfig: React.FC<ApiConfigProps> = ({
provider,
setProvider,
apiKeys,
setApiKey,
isProcessing,
}) => {
const providerDetails = {
gemini: {
name: "Google Gemini",
model: "gemini-2.5-flash-preview-04-17",
url: "https://aistudio.google.com/app/apikey",
urlText: "Google AI Studio",
focusColor: "focus:ring-blue-500 focus:border-blue-500",
},
openai: {
name: "OpenAI",
model: "gpt-4o",
url: "https://platform.openai.com/api-keys",
urlText: "OpenAI Dashboard",
focusColor: "focus:ring-green-500 focus:border-green-500",
},
anthropic: {
name: "Anthropic",
model: "claude-3-sonnet-20240229",
url: "https://console.anthropic.com/settings/keys",
urlText: "Anthropic Console",
focusColor: "focus:ring-purple-500 focus:border-purple-500",
}
};
const currentProvider = providerDetails[provider];
return (
<div className="mb-8">
<h2 className="text-2xl font-semibold mb-4 text-gray-200 flex items-center gap-3">
<KeyIcon className="w-6 h-6" />
AI Provider Configuration
</h2>
<div className="flex border-b border-gray-700 mb-6" role="tablist">
<ProviderTab providerName="gemini" activeProvider={provider} setProvider={setProvider} isProcessing={isProcessing}>
<GoogleIcon className="w-5 h-5" /> Gemini
</ProviderTab>
<ProviderTab providerName="openai" activeProvider={provider} setProvider={setProvider} isProcessing={isProcessing}>
<OpenAIIcon className="w-5 h-5" /> OpenAI
</ProviderTab>
<ProviderTab providerName="anthropic" activeProvider={provider} setProvider={setProvider} isProcessing={isProcessing}>
<AnthropicIcon className="w-5 h-5" /> Anthropic
</ProviderTab>
</div>
<div className="space-y-4">
<div>
<label htmlFor="api-key" className="block text-sm font-medium text-gray-400 mb-1">
{currentProvider.name} API Key
</label>
<input
id="api-key"
type="password"
value={apiKeys[provider]}
onChange={(e) => setApiKey(provider, e.target.value)}
disabled={isProcessing}
placeholder={`Enter your ${currentProvider.name} API Key`}
className={`w-full p-3 bg-gray-900/70 border-2 border-gray-600 rounded-xl text-gray-300 placeholder-gray-500 transition-all duration-200 ${currentProvider.focusColor}`}
/>
<p className="text-xs text-gray-500 mt-1">
Using model: <code className="bg-gray-700 px-1 rounded">{currentProvider.model}</code>. Get your key from <a href={currentProvider.url} target="_blank" rel="noopener noreferrer" className="underline hover:text-blue-400">{currentProvider.urlText}</a>.
</p>
</div>
</div>
</div>
);
};
export default ApiConfig;