138 lines
5.3 KiB
TypeScript
138 lines
5.3 KiB
TypeScript
import { useState, useEffect } from 'react'
|
|
import { invoke } from '@tauri-apps/api/tauri'
|
|
import { Settings, MessageSquare, Info } from 'lucide-react'
|
|
import { ChatInterface } from './components/ChatInterface'
|
|
import { ModelSelector } from './components/ModelSelector'
|
|
import { CharacterSelector } from './components/CharacterSelector'
|
|
import { SettingsPanel } from './components/SettingsPanel'
|
|
import { WindowControls } from './components/WindowControls'
|
|
import { useSettingsStore } from './stores/settingsStore'
|
|
import { getThemeManager } from './lib/theme'
|
|
import './App.css'
|
|
|
|
interface Keys {
|
|
openrouter_api_key: string | null
|
|
elevenlabs_api_key: string | null
|
|
}
|
|
|
|
function App() {
|
|
const [showSettings, setShowSettings] = useState(false)
|
|
const { openrouterApiKey, theme, setOpenRouterApiKey, setElevenLabsApiKey } = useSettingsStore()
|
|
|
|
// Initialize theme on mount
|
|
useEffect(() => {
|
|
const themeManager = getThemeManager()
|
|
themeManager.setTheme(theme)
|
|
}, [theme])
|
|
|
|
useEffect(() => {
|
|
// Fetch API keys from the backend on app load
|
|
async function fetchEnvKeys() {
|
|
try {
|
|
console.log('🔑 Fetching API keys from backend...')
|
|
const keys = await invoke<Keys>('get_env_keys')
|
|
console.log('🔑 Keys received from backend:', {
|
|
hasOpenRouter: !!keys.openrouter_api_key,
|
|
hasElevenLabs: !!keys.elevenlabs_api_key,
|
|
openRouterLength: keys.openrouter_api_key?.length || 0,
|
|
elevenLabsLength: keys.elevenlabs_api_key?.length || 0,
|
|
})
|
|
|
|
if (keys.openrouter_api_key) {
|
|
console.log('✅ Setting OpenRouter API key')
|
|
setOpenRouterApiKey(keys.openrouter_api_key)
|
|
} else {
|
|
console.warn('⚠️ No OpenRouter API key found in .env')
|
|
}
|
|
|
|
if (keys.elevenlabs_api_key) {
|
|
console.log('✅ Setting ElevenLabs API key')
|
|
setElevenLabsApiKey(keys.elevenlabs_api_key)
|
|
} else {
|
|
console.warn('⚠️ No ElevenLabs API key found in .env')
|
|
}
|
|
} catch (error) {
|
|
console.error('❌ Failed to fetch env keys from backend:', error)
|
|
}
|
|
}
|
|
|
|
fetchEnvKeys()
|
|
}, [setOpenRouterApiKey, setElevenLabsApiKey])
|
|
|
|
return (
|
|
<div className="h-screen flex flex-col bg-gradient-to-br from-blue-50 to-indigo-100 dark:from-gray-900 dark:to-gray-800">
|
|
{/* Window Controls (invisible, handles minimize to tray) */}
|
|
<WindowControls />
|
|
{/* Header */}
|
|
<header className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 bg-white/50 dark:bg-gray-800/50 backdrop-blur-sm">
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-full flex items-center justify-center">
|
|
<MessageSquare className="w-5 h-5 text-white" />
|
|
</div>
|
|
<div>
|
|
<h1 className="text-xl font-bold text-gray-800 dark:text-white">EVE</h1>
|
|
<p className="text-xs text-gray-600 dark:text-gray-400">Personal AI Assistant</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<CharacterSelector />
|
|
<ModelSelector />
|
|
<button
|
|
onClick={() => setShowSettings(true)}
|
|
className="p-2 hover:bg-white/50 dark:hover:bg-gray-700/50 rounded-lg transition"
|
|
>
|
|
<Settings className="w-5 h-5 text-gray-700 dark:text-gray-300" />
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
{/* Main Content */}
|
|
<div className="flex-1 overflow-hidden">
|
|
{!openrouterApiKey ? (
|
|
<div className="h-full flex items-center justify-center p-8">
|
|
<div className="max-w-md bg-white dark:bg-gray-800 rounded-2xl shadow-xl p-8 text-center">
|
|
<div className="w-16 h-16 bg-blue-100 dark:bg-blue-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
|
|
<Info className="w-8 h-8 text-blue-500" />
|
|
</div>
|
|
<h2 className="text-2xl font-bold text-gray-800 dark:text-white mb-4">
|
|
Welcome to EVE!
|
|
</h2>
|
|
<p className="text-gray-600 dark:text-gray-300 mb-6">
|
|
To get started, you'll need to set up your OpenRouter API key. OpenRouter gives you
|
|
access to GPT-4, Claude, Llama, and many other AI models.
|
|
</p>
|
|
<button
|
|
onClick={() => setShowSettings(true)}
|
|
className="px-6 py-3 bg-gradient-to-r from-blue-500 to-indigo-600
|
|
text-white rounded-lg hover:from-blue-600 hover:to-indigo-700
|
|
transition font-medium"
|
|
>
|
|
Configure Settings
|
|
</button>
|
|
<p className="text-sm text-gray-500 dark:text-gray-400 mt-4">
|
|
Don't have an API key?{' '}
|
|
<a
|
|
href="https://openrouter.ai/keys"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="text-blue-500 hover:underline"
|
|
>
|
|
Get one here →
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<ChatInterface />
|
|
)}
|
|
</div>
|
|
|
|
{/* Settings Panel */}
|
|
{showSettings && <SettingsPanel onClose={() => setShowSettings(false)} />}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default App
|