mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 20:23:36 +00:00
Move previously nested configs and hooks to global src/ folders to make them reusable across the application, reduce nesting, and establish clearer organization patterns. **New Global Structure:** - src/config/theme-options.ts (moved from appearance/config/) - src/config/api-providers.ts (moved from api-keys/config/) - src/hooks/use-scroll-tracking.ts (moved from settings-view/hooks/) **Changes:** - Move theme-options.ts to src/config/ - app-wide theme configuration - Move api-provider-config.ts to src/config/api-providers.ts - global API config - Move use-scroll-tracking.ts to src/hooks/ - reusable scroll navigation hook - Make useScrollTracking generic and more flexible with options object - Update all imports across settings-view components - Remove duplicate api-provider-config.ts from shared/ folder - Remove empty config/ folders (appearance/config, api-keys/config) **Benefits:** ✅ Single source of truth for themes and API providers ✅ Reusable scroll tracking hook available globally ✅ Cleaner structure with less nesting ✅ Better discoverability for developers ✅ No duplicate configuration files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
266 lines
7.3 KiB
TypeScript
266 lines
7.3 KiB
TypeScript
import { useState, useEffect } from "react";
|
|
import { useAppStore } from "@/store/app-store";
|
|
import { getElectronAPI } from "@/lib/electron";
|
|
import type { ProviderConfigParams } from "@/config/api-providers";
|
|
|
|
interface TestResult {
|
|
success: boolean;
|
|
message: string;
|
|
}
|
|
|
|
interface ApiKeyStatus {
|
|
hasAnthropicKey: boolean;
|
|
hasOpenAIKey: boolean;
|
|
hasGoogleKey: boolean;
|
|
}
|
|
|
|
/**
|
|
* Custom hook for managing API key state and operations
|
|
* Handles input values, visibility toggles, connection testing, and saving
|
|
*/
|
|
export function useApiKeyManagement() {
|
|
const { apiKeys, setApiKeys } = useAppStore();
|
|
|
|
// API key values
|
|
const [anthropicKey, setAnthropicKey] = useState(apiKeys.anthropic);
|
|
const [googleKey, setGoogleKey] = useState(apiKeys.google);
|
|
const [openaiKey, setOpenaiKey] = useState(apiKeys.openai);
|
|
|
|
// Visibility toggles
|
|
const [showAnthropicKey, setShowAnthropicKey] = useState(false);
|
|
const [showGoogleKey, setShowGoogleKey] = useState(false);
|
|
const [showOpenaiKey, setShowOpenaiKey] = useState(false);
|
|
|
|
// Test connection states
|
|
const [testingConnection, setTestingConnection] = useState(false);
|
|
const [testResult, setTestResult] = useState<TestResult | null>(null);
|
|
const [testingGeminiConnection, setTestingGeminiConnection] = useState(false);
|
|
const [geminiTestResult, setGeminiTestResult] = useState<TestResult | null>(
|
|
null
|
|
);
|
|
const [testingOpenaiConnection, setTestingOpenaiConnection] = useState(false);
|
|
const [openaiTestResult, setOpenaiTestResult] = useState<TestResult | null>(
|
|
null
|
|
);
|
|
|
|
// API key status from environment
|
|
const [apiKeyStatus, setApiKeyStatus] = useState<ApiKeyStatus | null>(null);
|
|
|
|
// Save state
|
|
const [saved, setSaved] = useState(false);
|
|
|
|
// Sync local state with store
|
|
useEffect(() => {
|
|
setAnthropicKey(apiKeys.anthropic);
|
|
setGoogleKey(apiKeys.google);
|
|
setOpenaiKey(apiKeys.openai);
|
|
}, [apiKeys]);
|
|
|
|
// Check API key status from environment on mount
|
|
useEffect(() => {
|
|
const checkApiKeyStatus = async () => {
|
|
const api = getElectronAPI();
|
|
if (api?.setup?.getApiKeys) {
|
|
try {
|
|
const status = await api.setup.getApiKeys();
|
|
if (status.success) {
|
|
setApiKeyStatus({
|
|
hasAnthropicKey: status.hasAnthropicKey,
|
|
hasOpenAIKey: status.hasOpenAIKey,
|
|
hasGoogleKey: status.hasGoogleKey,
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to check API key status:", error);
|
|
}
|
|
}
|
|
};
|
|
checkApiKeyStatus();
|
|
}, []);
|
|
|
|
// Test Anthropic/Claude connection
|
|
const handleTestAnthropicConnection = async () => {
|
|
setTestingConnection(true);
|
|
setTestResult(null);
|
|
|
|
try {
|
|
const response = await fetch("/api/claude/test", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ apiKey: anthropicKey }),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok && data.success) {
|
|
setTestResult({
|
|
success: true,
|
|
message: data.message || "Connection successful! Claude responded.",
|
|
});
|
|
} else {
|
|
setTestResult({
|
|
success: false,
|
|
message: data.error || "Failed to connect to Claude API.",
|
|
});
|
|
}
|
|
} catch {
|
|
setTestResult({
|
|
success: false,
|
|
message: "Network error. Please check your connection.",
|
|
});
|
|
} finally {
|
|
setTestingConnection(false);
|
|
}
|
|
};
|
|
|
|
// Test Google/Gemini connection
|
|
const handleTestGeminiConnection = async () => {
|
|
setTestingGeminiConnection(true);
|
|
setGeminiTestResult(null);
|
|
|
|
try {
|
|
const response = await fetch("/api/gemini/test", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ apiKey: googleKey }),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok && data.success) {
|
|
setGeminiTestResult({
|
|
success: true,
|
|
message: data.message || "Connection successful! Gemini responded.",
|
|
});
|
|
} else {
|
|
setGeminiTestResult({
|
|
success: false,
|
|
message: data.error || "Failed to connect to Gemini API.",
|
|
});
|
|
}
|
|
} catch {
|
|
setGeminiTestResult({
|
|
success: false,
|
|
message: "Network error. Please check your connection.",
|
|
});
|
|
} finally {
|
|
setTestingGeminiConnection(false);
|
|
}
|
|
};
|
|
|
|
// Test OpenAI connection
|
|
const handleTestOpenaiConnection = async () => {
|
|
setTestingOpenaiConnection(true);
|
|
setOpenaiTestResult(null);
|
|
|
|
try {
|
|
const api = getElectronAPI();
|
|
if (api?.testOpenAIConnection) {
|
|
const result = await api.testOpenAIConnection(openaiKey);
|
|
if (result.success) {
|
|
setOpenaiTestResult({
|
|
success: true,
|
|
message:
|
|
result.message || "Connection successful! OpenAI API responded.",
|
|
});
|
|
} else {
|
|
setOpenaiTestResult({
|
|
success: false,
|
|
message: result.error || "Failed to connect to OpenAI API.",
|
|
});
|
|
}
|
|
} else {
|
|
// Fallback to web API test
|
|
const response = await fetch("/api/openai/test", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ apiKey: openaiKey }),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok && data.success) {
|
|
setOpenaiTestResult({
|
|
success: true,
|
|
message:
|
|
data.message || "Connection successful! OpenAI API responded.",
|
|
});
|
|
} else {
|
|
setOpenaiTestResult({
|
|
success: false,
|
|
message: data.error || "Failed to connect to OpenAI API.",
|
|
});
|
|
}
|
|
}
|
|
} catch {
|
|
setOpenaiTestResult({
|
|
success: false,
|
|
message: "Network error. Please check your connection.",
|
|
});
|
|
} finally {
|
|
setTestingOpenaiConnection(false);
|
|
}
|
|
};
|
|
|
|
// Save API keys
|
|
const handleSave = () => {
|
|
setApiKeys({
|
|
anthropic: anthropicKey,
|
|
google: googleKey,
|
|
openai: openaiKey,
|
|
});
|
|
setSaved(true);
|
|
setTimeout(() => setSaved(false), 2000);
|
|
};
|
|
|
|
// Build provider config params for buildProviderConfigs
|
|
const providerConfigParams: ProviderConfigParams = {
|
|
apiKeys,
|
|
anthropic: {
|
|
value: anthropicKey,
|
|
setValue: setAnthropicKey,
|
|
show: showAnthropicKey,
|
|
setShow: setShowAnthropicKey,
|
|
testing: testingConnection,
|
|
onTest: handleTestAnthropicConnection,
|
|
result: testResult,
|
|
},
|
|
google: {
|
|
value: googleKey,
|
|
setValue: setGoogleKey,
|
|
show: showGoogleKey,
|
|
setShow: setShowGoogleKey,
|
|
testing: testingGeminiConnection,
|
|
onTest: handleTestGeminiConnection,
|
|
result: geminiTestResult,
|
|
},
|
|
openai: {
|
|
value: openaiKey,
|
|
setValue: setOpenaiKey,
|
|
show: showOpenaiKey,
|
|
setShow: setShowOpenaiKey,
|
|
testing: testingOpenaiConnection,
|
|
onTest: handleTestOpenaiConnection,
|
|
result: openaiTestResult,
|
|
},
|
|
};
|
|
|
|
return {
|
|
// Provider config params for buildProviderConfigs
|
|
providerConfigParams,
|
|
|
|
// API key status from environment
|
|
apiKeyStatus,
|
|
|
|
// Save handler and state
|
|
handleSave,
|
|
saved,
|
|
};
|
|
}
|