import React, { useEffect, useState } from 'react'; import { motion } from 'framer-motion'; import { FiServer, FiCpu, FiSettings, FiAlertCircle, FiX, } from 'react-icons/fi'; import { HederaSettings } from './settings/HederaSettings'; import { LLMSettings } from './settings/LLMSettings'; import { AdvancedSettings } from './settings/AdvancedSettings'; import { WalletSettings } from './settings/WalletSettings'; import { useConfigStore } from '../stores/configStore'; import { useAgentStore } from '../stores/agentStore'; import { Button } from '../components/ui/Button'; import { Card, CardContent } from '../components/ui/Card'; import { Tabs, TabsList, TabsTrigger, TabsContent, } from '../components/ui/tabs'; import Typography from '../components/ui/Typography'; import { cn } from '../lib/utils'; interface SettingsPageProps {} type TabKey = 'hedera' | 'wallet' | 'llm' | 'advanced'; interface Tab { key: TabKey; label: string; icon: React.ElementType; component: React.ComponentType; } const tabs: Tab[] = [ { key: 'hedera', label: 'Hedera', icon: FiServer, component: HederaSettings }, { key: 'wallet', label: 'Wallet', icon: FiServer, component: WalletSettings }, { key: 'llm', label: 'AI Models', icon: FiCpu, component: LLMSettings }, { key: 'advanced', label: 'Advanced', icon: FiSettings, component: AdvancedSettings, }, ]; const tabGradients = { hedera: 'from-hgo-purple to-hgo-blue', llm: 'from-hgo-blue to-hgo-green', advanced: 'from-hgo-green to-hgo-purple', }; const SettingsPage: React.FC = () => { const [activeTab, setActiveTab] = useState('hedera'); const { isLoading, loadConfig, saveConfig, error, clearError, isHederaConfigValid, isLLMConfigValid, } = useConfigStore(); const [hasChanges, setHasChanges] = useState(false); const [saveTimeout, setSaveTimeout] = useState(null); const [configNeverSaved, setConfigNeverSaved] = useState(false); useEffect(() => { loadConfig().then(() => { const checkConfigSaved = async () => { try { const result = await window.electron.loadConfig(); if (!result) { setConfigNeverSaved(true); setHasChanges(true); } } catch (error) { setConfigNeverSaved(true); setHasChanges(true); } }; checkConfigSaved(); }); }, [loadConfig]); useEffect(() => { const unsubscribe = useConfigStore.subscribe((state, prevState) => { const changed = JSON.stringify(state.config) !== JSON.stringify(prevState.config); if (changed) { try { console.debug('[SettingsPage] config changed; scheduling save debounce'); } catch {} setHasChanges(true); if (saveTimeout) { clearTimeout(saveTimeout); } const hederaValid = isHederaConfigValid(); const llmValid = isLLMConfigValid(); const advancedChanged = Boolean( state.config?.advanced && JSON.stringify(state.config.advanced) !== JSON.stringify(prevState.config?.advanced) ); const shouldAutoSave = (hederaValid && llmValid) || advancedChanged; if (shouldAutoSave) { const timeout = setTimeout(async () => { try { try { console.debug('[SettingsPage] auto-saving config'); } catch {} await saveConfig(); setHasChanges(false); } catch (error) {} }, 2000); setSaveTimeout(timeout); } } }); return () => { unsubscribe(); if (saveTimeout) { clearTimeout(saveTimeout); } }; }, [saveConfig, isHederaConfigValid, isLLMConfigValid, saveTimeout]); const { isConnected, disconnect, connect } = useAgentStore(); const handleSaveConfiguration = async () => { try { const oldConfig = localStorage.getItem('app-config'); await saveConfig(); setHasChanges(false); setConfigNeverSaved(false); const newConfig = localStorage.getItem('app-config'); if (oldConfig && newConfig) { const oldParsed = JSON.parse(oldConfig); const newParsed = JSON.parse(newConfig); const modelOrProviderChanged = oldParsed.openai?.model !== newParsed.openai?.model || oldParsed.anthropic?.model !== newParsed.anthropic?.model || oldParsed.llmProvider !== newParsed.llmProvider; if (modelOrProviderChanged && isConnected) { await disconnect(); setTimeout(async () => { await connect(); }, 500); } } } catch (error) {} }; const handleCancel = async () => { await loadConfig(); setHasChanges(false); }; const isConfigValid = isHederaConfigValid() && isLLMConfigValid(); if (isLoading) { return (
Loading configuration...
); } return (
Settings Configure your agent's connection to Hedera, AI models, and advanced options
{error && (
)} setActiveTab(value as TabKey)} >
{tabs.map((tab) => { const Icon = tab.icon; return ( ); })}
{configNeverSaved && isConfigValid && (
Configuration has never been saved. Click Save to persist your settings. )} {hasChanges && !configNeverSaved && isConfigValid && (
Configuration will auto-save in 2 seconds... )} {hasChanges && !isConfigValid && ( Please complete all required fields )}
); }; export default SettingsPage;