import { useState, useEffect } from 'react'; import { Button } from './ui/button'; import { Input } from './ui/input'; import { Key, Plus, Trash2, Eye, EyeOff, Copy, Check, Github } from 'lucide-react'; import { authenticatedFetch } from '../utils/api'; function ApiKeysSettings() { const [apiKeys, setApiKeys] = useState([]); const [githubTokens, setGithubTokens] = useState([]); const [loading, setLoading] = useState(true); const [showNewKeyForm, setShowNewKeyForm] = useState(false); const [showNewTokenForm, setShowNewTokenForm] = useState(false); const [newKeyName, setNewKeyName] = useState(''); const [newTokenName, setNewTokenName] = useState(''); const [newGithubToken, setNewGithubToken] = useState(''); const [showToken, setShowToken] = useState({}); const [copiedKey, setCopiedKey] = useState(null); const [newlyCreatedKey, setNewlyCreatedKey] = useState(null); useEffect(() => { fetchData(); }, []); const fetchData = async () => { try { setLoading(true); // Fetch API keys const apiKeysRes = await authenticatedFetch('/api/settings/api-keys'); const apiKeysData = await apiKeysRes.json(); setApiKeys(apiKeysData.apiKeys || []); // Fetch GitHub tokens const githubRes = await authenticatedFetch('/api/settings/credentials?type=github_token'); const githubData = await githubRes.json(); setGithubTokens(githubData.credentials || []); } catch (error) { console.error('Error fetching settings:', error); } finally { setLoading(false); } }; const createApiKey = async () => { if (!newKeyName.trim()) return; try { const res = await authenticatedFetch('/api/settings/api-keys', { method: 'POST', body: JSON.stringify({ keyName: newKeyName }) }); const data = await res.json(); if (data.success) { setNewlyCreatedKey(data.apiKey); setNewKeyName(''); setShowNewKeyForm(false); fetchData(); } } catch (error) { console.error('Error creating API key:', error); } }; const deleteApiKey = async (keyId) => { if (!confirm('Are you sure you want to delete this API key?')) return; try { await authenticatedFetch(`/api/settings/api-keys/${keyId}`, { method: 'DELETE' }); fetchData(); } catch (error) { console.error('Error deleting API key:', error); } }; const toggleApiKey = async (keyId, isActive) => { try { await authenticatedFetch(`/api/settings/api-keys/${keyId}/toggle`, { method: 'PATCH', body: JSON.stringify({ isActive: !isActive }) }); fetchData(); } catch (error) { console.error('Error toggling API key:', error); } }; const createGithubToken = async () => { if (!newTokenName.trim() || !newGithubToken.trim()) return; try { const res = await authenticatedFetch('/api/settings/credentials', { method: 'POST', body: JSON.stringify({ credentialName: newTokenName, credentialType: 'github_token', credentialValue: newGithubToken }) }); const data = await res.json(); if (data.success) { setNewTokenName(''); setNewGithubToken(''); setShowNewTokenForm(false); fetchData(); } } catch (error) { console.error('Error creating GitHub token:', error); } }; const deleteGithubToken = async (tokenId) => { if (!confirm('Are you sure you want to delete this GitHub token?')) return; try { await authenticatedFetch(`/api/settings/credentials/${tokenId}`, { method: 'DELETE' }); fetchData(); } catch (error) { console.error('Error deleting GitHub token:', error); } }; const toggleGithubToken = async (tokenId, isActive) => { try { await authenticatedFetch(`/api/settings/credentials/${tokenId}/toggle`, { method: 'PATCH', body: JSON.stringify({ isActive: !isActive }) }); fetchData(); } catch (error) { console.error('Error toggling GitHub token:', error); } }; const copyToClipboard = (text, id) => { navigator.clipboard.writeText(text); setCopiedKey(id); setTimeout(() => setCopiedKey(null), 2000); }; if (loading) { return
This is the only time you'll see this key. Store it securely.
{newlyCreatedKey.apiKey}
Generate API keys to access the external API from other applications.
{showNewKeyForm && (No API keys created yet.
) : ( apiKeys.map((key) => ({key.api_key}
Add GitHub Personal Access Tokens to clone private repositories via the external API.
{showNewTokenForm && (No GitHub tokens added yet.
) : ( githubTokens.map((token) => (Learn how to use the external API to trigger Claude/Cursor sessions from your applications.
View API Documentation →