'use client'; import { useState, useEffect } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Button } from '@/components/ui/button'; import { Separator } from '@/components/ui/separator'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; import { useSettingsStore } from '@/stores/settings-store'; import { getApiBaseUrl, getWsBaseUrl, getBackendUrl, setBackendUrl } from '@/lib/constants'; import { showSuccess } from '@/lib/toast'; import { useTranslation } from '@/lib/i18n'; import { ServerLogViewer } from '@/components/server-log-viewer'; import { ServerStatusDashboard } from '@/components/server-status-dashboard'; // TODO(M2+): read actual values from the backend via /api/system/info. // 暫時用 userAgent 判斷平台顯示對應路徑。 function getPlatformDataDir(): string { if (typeof navigator === 'undefined') return '(unknown)'; if (/Windows/i.test(navigator.userAgent)) return '%APPDATA%\\visiona-local'; if (/Linux/i.test(navigator.userAgent)) return '~/.local/share/visiona-local'; return '~/Library/Application Support/visiona-local'; } const DATA_DIR_PLACEHOLDER = getPlatformDataDir(); const MODELS_UPLOAD_PATH_PLACEHOLDER = DATA_DIR_PLACEHOLDER + (DATA_DIR_PLACEHOLDER.includes('\\') ? '\\models' : '/models'); const BUNDLED_PYTHON_PLACEHOLDER = 'Bundled Python 3.12 (ready)'; export default function SettingsPage() { const { t } = useTranslation(); const { theme, language, setLanguage, resetToDefaults } = useSettingsStore(); const [backendUrlInput, setBackendUrlInput] = useState(''); const [apiUrl, setApiUrl] = useState(''); const [wsUrl, setWsUrl] = useState(''); useEffect(() => { setBackendUrlInput(getBackendUrl()); setApiUrl(getApiBaseUrl()); setWsUrl(getWsBaseUrl()); }, []); function handleSaveBackendUrl() { setBackendUrl(backendUrlInput); setApiUrl(getApiBaseUrl()); setWsUrl(getWsBaseUrl()); showSuccess(t('settings.backendUrlSaved')); } // Derived port for Advanced tab — parsed from backend URL if possible. let serverPortDisplay = '3721'; try { const u = new URL(apiUrl || 'http://localhost:3721'); if (u.port) serverPortDisplay = u.port; } catch { /* ignore */ } return (
{t('settings.subtitle')}
{t('settings.general.languageRestartHint')}
{t('settings.general.themeFollowSystemHint')}
{t('settings.general.dataDirectoryHint')}
{t('settings.hardware.runtimeModeHint')}
{t('settings.hardware.pythonModeHint')}
{t('settings.models.presetModelsEmpty')}
{t('settings.models.uploadPathHint')}
{t('settings.backendUrlHint')}
{t('settings.hardware.serverPortHint')}
{t('settings.advanced.resetAllHint')}