({ isOpen, onClose, initialTab = 'general' }: GlobalSettingsProps)
| 106 | } |
| 107 | |
| 108 | export default function GlobalSettings({ isOpen, onClose, initialTab = 'general' }: GlobalSettingsProps) { |
| 109 | const [activeTab, setActiveTab] = useState<'general' | 'ai-agents' | 'services' | 'about'>(initialTab); |
| 110 | const [serviceModalOpen, setServiceModalOpen] = useState(false); |
| 111 | const [selectedProvider, setSelectedProvider] = useState<'github' | 'supabase' | 'vercel' | null>(null); |
| 112 | const [tokens, setTokens] = useState<{ [key: string]: ServiceToken | null }>({ |
| 113 | github: null, |
| 114 | supabase: null, |
| 115 | vercel: null |
| 116 | }); |
| 117 | const [cliStatus, setCLIStatus] = useState<CLIStatus>({}); |
| 118 | const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null); |
| 119 | const { settings: globalSettings, setSettings: setGlobalSettings, refresh: refreshGlobalSettings } = useGlobalSettings(); |
| 120 | const [isLoading, setIsLoading] = useState(false); |
| 121 | const [saveMessage, setSaveMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null); |
| 122 | const [installModalOpen, setInstallModalOpen] = useState(false); |
| 123 | const [selectedCLI, setSelectedCLI] = useState<CLIOption | null>(null); |
| 124 | const [apiKeyVisibility, setApiKeyVisibility] = useState<Record<string, boolean>>({}); |
| 125 | |
| 126 | // Show toast function |
| 127 | const showToast = (message: string, type: 'success' | 'error') => { |
| 128 | setToast({ message, type }); |
| 129 | setTimeout(() => setToast(null), 3000); |
| 130 | }; |
| 131 | |
| 132 | const loadAllTokens = useCallback(async () => { |
| 133 | const providers = ['github', 'supabase', 'vercel']; |
| 134 | const newTokens: { [key: string]: ServiceToken | null } = {}; |
| 135 | |
| 136 | for (const provider of providers) { |
| 137 | try { |
| 138 | const response = await fetch(`${API_BASE}/api/tokens/${provider}`); |
| 139 | if (response.ok) { |
| 140 | newTokens[provider] = await response.json(); |
| 141 | } else { |
| 142 | newTokens[provider] = null; |
| 143 | } |
| 144 | } catch { |
| 145 | newTokens[provider] = null; |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | setTokens(newTokens); |
| 150 | }, []); |
| 151 | |
| 152 | const handleServiceClick = (provider: 'github' | 'supabase' | 'vercel') => { |
| 153 | setSelectedProvider(provider); |
| 154 | setServiceModalOpen(true); |
| 155 | }; |
| 156 | |
| 157 | const handleServiceModalClose = () => { |
| 158 | setServiceModalOpen(false); |
| 159 | setSelectedProvider(null); |
| 160 | loadAllTokens(); // Reload tokens after modal closes |
| 161 | }; |
| 162 | |
| 163 | const loadGlobalSettings = useCallback(async () => { |
| 164 | try { |
| 165 | const response = await fetch(`${API_BASE}/api/settings/global`); |
nothing calls this directly
no test coverage detected