un wanted ai configs removed
This commit is contained in:
parent
068faad462
commit
b9a8c5bf52
@ -11,10 +11,6 @@ import { toast } from 'sonner';
|
||||
|
||||
interface AIConfigData {
|
||||
aiEnabled: boolean;
|
||||
aiProvider: 'claude' | 'openai' | 'gemini';
|
||||
claudeApiKey: string;
|
||||
openaiApiKey: string;
|
||||
geminiApiKey: string;
|
||||
aiRemarkGeneration: boolean;
|
||||
maxRemarkChars: number;
|
||||
}
|
||||
@ -22,19 +18,10 @@ interface AIConfigData {
|
||||
export function AIConfig() {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [showApiKeys, setShowApiKeys] = useState<Record<string, boolean>>({
|
||||
claude: false,
|
||||
openai: false,
|
||||
gemini: false
|
||||
});
|
||||
const [config, setConfig] = useState<AIConfigData>({
|
||||
aiEnabled: true,
|
||||
aiProvider: 'claude',
|
||||
claudeApiKey: '',
|
||||
openaiApiKey: '',
|
||||
geminiApiKey: '',
|
||||
aiRemarkGeneration: true,
|
||||
maxRemarkChars: 500
|
||||
maxRemarkChars: 2000
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@ -54,10 +41,6 @@ export function AIConfig() {
|
||||
|
||||
setConfig({
|
||||
aiEnabled: configMap['AI_ENABLED'] === 'true',
|
||||
aiProvider: (configMap['AI_PROVIDER'] || 'claude') as 'claude' | 'openai' | 'gemini',
|
||||
claudeApiKey: configMap['CLAUDE_API_KEY'] || '',
|
||||
openaiApiKey: configMap['OPENAI_API_KEY'] || '',
|
||||
geminiApiKey: configMap['GEMINI_API_KEY'] || '',
|
||||
aiRemarkGeneration: configMap['AI_REMARK_GENERATION_ENABLED'] === 'true',
|
||||
maxRemarkChars: parseInt(configMap['AI_MAX_REMARK_LENGTH'] || '2000')
|
||||
});
|
||||
@ -76,10 +59,6 @@ export function AIConfig() {
|
||||
// Save all configurations
|
||||
await Promise.all([
|
||||
updateConfiguration('AI_ENABLED', config.aiEnabled.toString()),
|
||||
updateConfiguration('AI_PROVIDER', config.aiProvider),
|
||||
updateConfiguration('CLAUDE_API_KEY', config.claudeApiKey),
|
||||
updateConfiguration('OPENAI_API_KEY', config.openaiApiKey),
|
||||
updateConfiguration('GEMINI_API_KEY', config.geminiApiKey),
|
||||
updateConfiguration('AI_REMARK_GENERATION_ENABLED', config.aiRemarkGeneration.toString()),
|
||||
updateConfiguration('AI_MAX_REMARK_LENGTH', config.maxRemarkChars.toString())
|
||||
]);
|
||||
@ -100,19 +79,6 @@ export function AIConfig() {
|
||||
setConfig(prev => ({ ...prev, ...updates }));
|
||||
};
|
||||
|
||||
const toggleApiKeyVisibility = (provider: 'claude' | 'openai' | 'gemini') => {
|
||||
setShowApiKeys(prev => ({
|
||||
...prev,
|
||||
[provider]: !prev[provider]
|
||||
}));
|
||||
};
|
||||
|
||||
const maskApiKey = (key: string): string => {
|
||||
if (!key || key.length === 0) return '';
|
||||
if (key.length <= 8) return '••••••••';
|
||||
return key.substring(0, 4) + '••••••••' + key.substring(key.length - 4);
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Card className="shadow-lg border-0 rounded-md">
|
||||
@ -134,7 +100,7 @@ export function AIConfig() {
|
||||
<div>
|
||||
<CardTitle className="text-lg font-semibold text-gray-900">AI Features Configuration</CardTitle>
|
||||
<CardDescription className="text-sm text-gray-600">
|
||||
Configure AI provider, API keys, and enable/disable AI-powered features
|
||||
Configure Vertex AI Gemini settings and enable/disable AI-powered features
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
@ -142,18 +108,7 @@ export function AIConfig() {
|
||||
<CardContent className="space-y-6">
|
||||
<AIProviderSettings
|
||||
aiEnabled={config.aiEnabled}
|
||||
aiProvider={config.aiProvider}
|
||||
claudeApiKey={config.claudeApiKey}
|
||||
openaiApiKey={config.openaiApiKey}
|
||||
geminiApiKey={config.geminiApiKey}
|
||||
showApiKeys={showApiKeys}
|
||||
onAiEnabledChange={(enabled) => updateConfig({ aiEnabled: enabled })}
|
||||
onProviderChange={(provider) => updateConfig({ aiProvider: provider })}
|
||||
onClaudeApiKeyChange={(key) => updateConfig({ claudeApiKey: key })}
|
||||
onOpenaiApiKeyChange={(key) => updateConfig({ openaiApiKey: key })}
|
||||
onGeminiApiKeyChange={(key) => updateConfig({ geminiApiKey: key })}
|
||||
onToggleApiKeyVisibility={toggleApiKeyVisibility}
|
||||
maskApiKey={maskApiKey}
|
||||
/>
|
||||
|
||||
<Separator />
|
||||
|
||||
@ -1,63 +1,25 @@
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select';
|
||||
import { Brain, Eye, EyeOff, Key } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Brain } from 'lucide-react';
|
||||
|
||||
interface AIProviderSettingsProps {
|
||||
aiEnabled: boolean;
|
||||
aiProvider: 'claude' | 'openai' | 'gemini';
|
||||
claudeApiKey: string;
|
||||
openaiApiKey: string;
|
||||
geminiApiKey: string;
|
||||
showApiKeys: Record<string, boolean>;
|
||||
onAiEnabledChange: (enabled: boolean) => void;
|
||||
onProviderChange: (provider: 'claude' | 'openai' | 'gemini') => void;
|
||||
onClaudeApiKeyChange: (key: string) => void;
|
||||
onOpenaiApiKeyChange: (key: string) => void;
|
||||
onGeminiApiKeyChange: (key: string) => void;
|
||||
onToggleApiKeyVisibility: (provider: 'claude' | 'openai' | 'gemini') => void;
|
||||
maskApiKey: (key: string) => string;
|
||||
}
|
||||
|
||||
const PROVIDERS = [
|
||||
{ value: 'claude', label: 'Claude (Anthropic)', description: 'Advanced AI by Anthropic' },
|
||||
{ value: 'openai', label: 'OpenAI (GPT-4)', description: 'GPT-4 by OpenAI' },
|
||||
{ value: 'gemini', label: 'Gemini (Google)', description: 'Gemini by Google' }
|
||||
];
|
||||
|
||||
export function AIProviderSettings({
|
||||
aiEnabled,
|
||||
aiProvider,
|
||||
claudeApiKey,
|
||||
openaiApiKey,
|
||||
geminiApiKey,
|
||||
showApiKeys,
|
||||
onAiEnabledChange,
|
||||
onProviderChange,
|
||||
onClaudeApiKeyChange,
|
||||
onOpenaiApiKeyChange,
|
||||
onGeminiApiKeyChange,
|
||||
onToggleApiKeyVisibility,
|
||||
maskApiKey
|
||||
onAiEnabledChange
|
||||
}: AIProviderSettingsProps) {
|
||||
return (
|
||||
<Card className="border-0 shadow-sm">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Brain className="w-5 h-5 text-re-green" />
|
||||
<CardTitle className="text-base font-semibold">AI Provider & API Keys</CardTitle>
|
||||
<CardTitle className="text-base font-semibold">Vertex AI Gemini Configuration</CardTitle>
|
||||
</div>
|
||||
<CardDescription className="text-sm">
|
||||
Select your AI provider and configure API keys
|
||||
Configure AI features. Model and region are configured via environment variables.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
@ -74,145 +36,7 @@ export function AIProviderSettings({
|
||||
onCheckedChange={onAiEnabledChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{aiEnabled && (
|
||||
<>
|
||||
{/* Provider Selection */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="ai-provider" className="text-sm font-medium">
|
||||
AI Provider
|
||||
</Label>
|
||||
<Select value={aiProvider} onValueChange={(value: any) => onProviderChange(value)}>
|
||||
<SelectTrigger
|
||||
id="ai-provider"
|
||||
className="border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20"
|
||||
>
|
||||
<SelectValue placeholder="Select AI provider" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{PROVIDERS.map((provider) => (
|
||||
<SelectItem key={provider.value} value={provider.value}>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium">{provider.label}</span>
|
||||
<span className="text-xs text-muted-foreground">-</span>
|
||||
<span className="text-xs text-muted-foreground">{provider.description}</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{/* API Keys for each provider */}
|
||||
<div className="space-y-4 pt-2">
|
||||
<Label className="text-sm font-medium flex items-center gap-2">
|
||||
<Key className="w-4 h-4" />
|
||||
API Keys
|
||||
</Label>
|
||||
|
||||
{/* Claude API Key */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="claude-key" className="text-xs text-muted-foreground">
|
||||
Claude API Key
|
||||
</Label>
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
id="claude-key"
|
||||
type={showApiKeys.claude ? 'text' : 'password'}
|
||||
value={claudeApiKey}
|
||||
onChange={(e) => onClaudeApiKeyChange(e.target.value)}
|
||||
placeholder={showApiKeys.claude ? "sk-ant-..." : maskApiKey(claudeApiKey) || "sk-ant-..."}
|
||||
className="border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20 font-mono text-sm"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => onToggleApiKeyVisibility('claude')}
|
||||
className="border-gray-200"
|
||||
>
|
||||
{showApiKeys.claude ? (
|
||||
<EyeOff className="w-4 h-4" />
|
||||
) : (
|
||||
<Eye className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Get your API key from console.anthropic.com
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* OpenAI API Key */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="openai-key" className="text-xs text-muted-foreground">
|
||||
OpenAI API Key
|
||||
</Label>
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
id="openai-key"
|
||||
type={showApiKeys.openai ? 'text' : 'password'}
|
||||
value={openaiApiKey}
|
||||
onChange={(e) => onOpenaiApiKeyChange(e.target.value)}
|
||||
placeholder={showApiKeys.openai ? "sk-..." : maskApiKey(openaiApiKey) || "sk-..."}
|
||||
className="border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20 font-mono text-sm"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => onToggleApiKeyVisibility('openai')}
|
||||
className="border-gray-200"
|
||||
>
|
||||
{showApiKeys.openai ? (
|
||||
<EyeOff className="w-4 h-4" />
|
||||
) : (
|
||||
<Eye className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Get your API key from platform.openai.com
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Gemini API Key */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="gemini-key" className="text-xs text-muted-foreground">
|
||||
Gemini API Key
|
||||
</Label>
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
id="gemini-key"
|
||||
type={showApiKeys.gemini ? 'text' : 'password'}
|
||||
value={geminiApiKey}
|
||||
onChange={(e) => onGeminiApiKeyChange(e.target.value)}
|
||||
placeholder={showApiKeys.gemini ? "AIza..." : maskApiKey(geminiApiKey) || "AIza..."}
|
||||
className="border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20 font-mono text-sm"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => onToggleApiKeyVisibility('gemini')}
|
||||
className="border-gray-200"
|
||||
>
|
||||
{showApiKeys.gemini ? (
|
||||
<EyeOff className="w-4 h-4" />
|
||||
) : (
|
||||
<Eye className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Get your API key from ai.google.dev
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user