'use client'; import * as React from 'react'; import { type ImageProvider, PROVIDER_CONFIGS } from '@/lib/api-config'; // Storage key for localStorage const STORAGE_KEY = 'imageforge-api-keys'; // Map provider to their storage key names const PROVIDER_STORAGE_KEYS: Record = { openai: 'openai', google: 'google', qwen: 'qwen', }; export interface ApiKeysState { openai: string; google: string; qwen: string; } interface ApiKeysContextType { apiKeys: ApiKeysState; setApiKey: (provider: ImageProvider, key: string) => void; getApiKey: (provider: ImageProvider) => string; clearApiKey: (provider: ImageProvider) => void; clearAllKeys: () => void; hasKey: (provider: ImageProvider) => boolean; isOpen: boolean; setIsOpen: (open: boolean) => void; } const defaultState: ApiKeysState = { openai: '', google: '', qwen: '', }; const ApiKeysContext = React.createContext(undefined); export function ApiKeysProvider({ children }: { children: React.ReactNode }) { const [apiKeys, setApiKeys] = React.useState(defaultState); const [isOpen, setIsOpen] = React.useState(false); const [isInitialized, setIsInitialized] = React.useState(false); // Load keys from localStorage on mount React.useEffect(() => { try { const stored = localStorage.getItem(STORAGE_KEY); if (stored) { const parsed = JSON.parse(stored) as Partial; setApiKeys({ openai: parsed.openai || '', google: parsed.google || '', qwen: parsed.qwen || '', }); } } catch (error) { console.error('Failed to load API keys from localStorage:', error); } setIsInitialized(true); }, []); // Save keys to localStorage whenever they change React.useEffect(() => { if (isInitialized) { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(apiKeys)); } catch (error) { console.error('Failed to save API keys to localStorage:', error); } } }, [apiKeys, isInitialized]); const setApiKey = React.useCallback((provider: ImageProvider, key: string) => { const storageKey = PROVIDER_STORAGE_KEYS[provider]; setApiKeys(prev => ({ ...prev, [storageKey]: key, })); }, []); const getApiKey = React.useCallback((provider: ImageProvider) => { const storageKey = PROVIDER_STORAGE_KEYS[provider]; return apiKeys[storageKey as keyof ApiKeysState] || ''; }, [apiKeys]); const clearApiKey = React.useCallback((provider: ImageProvider) => { const storageKey = PROVIDER_STORAGE_KEYS[provider]; setApiKeys(prev => ({ ...prev, [storageKey]: '', })); }, []); const clearAllKeys = React.useCallback(() => { setApiKeys(defaultState); }, []); const hasKey = React.useCallback((provider: ImageProvider) => { const key = getApiKey(provider); return key.trim().length > 0; }, [getApiKey]); const value = React.useMemo(() => ({ apiKeys, setApiKey, getApiKey, clearApiKey, clearAllKeys, hasKey, isOpen, setIsOpen, }), [apiKeys, setApiKey, getApiKey, clearApiKey, clearAllKeys, hasKey, isOpen]); return ( {children} ); } export function useApiKeys() { const context = React.useContext(ApiKeysContext); if (context === undefined) { throw new Error('useApiKeys must be used within an ApiKeysProvider'); } return context; }