import { useState, useEffect } from "react"; import { useRouter } from "@tanstack/react-router"; import { ArrowLeft, ExternalLink, KeyRound, Info, Circle, Settings as SettingsIcon, GiftIcon, Trash2, } from "lucide-react"; import { useSettings } from "@/hooks/useSettings"; import { PROVIDER_TO_ENV_VAR, PROVIDERS } from "@/constants/models"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Skeleton } from "@/components/ui/skeleton"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "@/components/ui/accordion"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { IpcClient } from "@/ipc/ipc_client"; interface ProviderSettingsPageProps { provider: string; } // Helper function to mask ENV API keys (still needed for env vars) const maskEnvApiKey = (key: string | undefined): string => { if (!key) return "Not Set"; if (key.length < 8) return "****"; return `${key.substring(0, 4)}...${key.substring(key.length - 4)}`; }; export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) { const { settings, envVars, loading: settingsLoading, error: settingsError, updateSettings, } = useSettings(); const [apiKeyInput, setApiKeyInput] = useState(""); const [isSaving, setIsSaving] = useState(false); const [saveError, setSaveError] = useState(null); const router = useRouter(); // Find provider details const providerInfo = PROVIDERS[provider as keyof typeof PROVIDERS]; const providerDisplayName = providerInfo?.displayName || provider.charAt(0).toUpperCase() + provider.slice(1); const providerWebsiteUrl = providerInfo?.websiteUrl; const hasFreeTier = providerInfo?.hasFreeTier; const envVarName = PROVIDER_TO_ENV_VAR[provider]; const envApiKey = envVars[envVarName]; const userApiKey = settings?.providerSettings?.[provider]?.apiKey?.value; // --- Configuration Logic --- Updated Priority --- const isValidUserKey = !!userApiKey && !userApiKey.startsWith("Invalid Key") && userApiKey !== "Not Set"; const hasEnvKey = !!envApiKey; const isConfigured = isValidUserKey || hasEnvKey; // Configured if either is set // Settings key takes precedence if it's valid const activeKeySource = isValidUserKey ? "settings" : hasEnvKey ? "env" : "none"; // --- Accordion Logic --- const defaultAccordionValue = []; if (isValidUserKey || !hasEnvKey) { // If user key is set OR env key is NOT set, open the settings accordion item defaultAccordionValue.push("settings-key"); } if (hasEnvKey) { defaultAccordionValue.push("env-key"); } // --- Save Handler --- const handleSaveKey = async () => { if (!apiKeyInput) { setSaveError("API Key cannot be empty."); return; } setIsSaving(true); setSaveError(null); try { await updateSettings({ providerSettings: { ...settings?.providerSettings, [provider]: { ...(settings?.providerSettings?.[provider] || {}), apiKey: { value: apiKeyInput, }, }, }, }); setApiKeyInput(""); // Clear input on success // Optionally show a success message } catch (error: any) { console.error("Error saving API key:", error); setSaveError(error.message || "Failed to save API key."); } finally { setIsSaving(false); } }; // --- Delete Handler --- const handleDeleteKey = async () => { setIsSaving(true); setSaveError(null); try { await updateSettings({ providerSettings: { ...settings?.providerSettings, [provider]: { ...(settings?.providerSettings?.[provider] || {}), apiKey: undefined, }, }, }); // Optionally show a success message } catch (error: any) { console.error("Error deleting API key:", error); setSaveError(error.message || "Failed to delete API key."); } finally { setIsSaving(false); } }; // Effect to clear input error when input changes useEffect(() => { if (saveError) { setSaveError(null); } }, [apiKeyInput]); return (

Configure {providerDisplayName}

{settingsLoading ? ( ) : ( )} {settingsLoading ? "Loading..." : isConfigured ? "Setup Complete" : "Not Setup"}
{!settingsLoading && hasFreeTier && ( Free tier available )}
{providerWebsiteUrl && !settingsLoading && ( )} {settingsLoading ? (
) : settingsError ? ( Error Loading Settings Could not load configuration data: {settingsError.message} ) : ( API Key from Settings {isValidUserKey && ( Current Key (Settings)

{userApiKey}

{activeKeySource === "settings" && (

This key is currently active.

)}
)}
setApiKeyInput(e.target.value)} placeholder={`Enter new ${providerDisplayName} API Key here`} className={`flex-grow ${ saveError ? "border-red-500" : "" }`} />
{saveError && (

{saveError}

)}

Setting a key here will override the environment variable (if set).

API Key from Environment Variable {hasEnvKey ? ( Environment Variable Key ({envVarName})

{maskEnvApiKey(envApiKey)}

{activeKeySource === "env" && (

This key is currently active (no settings key set).

)} {activeKeySource === "settings" && (

This key is currently being overridden by the key set in Settings.

)}
) : ( Environment Variable Not Set The{" "} {envVarName} {" "} environment variable is not set. )}

This key is set outside the application. If present, it will be used only if no key is configured in the Settings section above. Requires app restart to detect changes.

)}
); }