| 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; | |