@@ -36,6 +36,7 @@ import { FeatureSetsPage } from '@/features/featuresets';
3636import { ClientsPage } from '@/features/clients' ;
3737import { ServersPage } from '@/features/servers' ;
3838import { SpacesPage } from '@/features/spaces' ;
39+ import { SettingsPage } from '@/features/settings' ;
3940import { useGatewayEvents , useServerStatusEvents } from '@/hooks/useDomainEvents' ;
4041
4142type NavItem = 'home' | 'registry' | 'servers' | 'spaces' | 'featuresets' | 'clients' | 'settings' ;
@@ -46,6 +47,25 @@ function AppContent() {
4647
4748 const [ activeNav , setActiveNav ] = useState < NavItem > ( 'home' ) ;
4849
50+ // Auto-check for updates on startup (silent check after 5 seconds)
51+ useEffect ( ( ) => {
52+ const checkForUpdates = async ( ) => {
53+ try {
54+ const { check } = await import ( '@tauri-apps/plugin-updater' ) ;
55+ const update = await check ( ) ;
56+ if ( update ) {
57+ console . log ( `[Auto-Update] Update available: ${ update . version } ` ) ;
58+ // User can check Settings page to see the update
59+ }
60+ } catch ( error ) {
61+ console . error ( '[Auto-Update] Failed to check for updates:' , error ) ;
62+ }
63+ } ;
64+
65+ const timer = setTimeout ( checkForUpdates , 5000 ) ;
66+ return ( ) => clearTimeout ( timer ) ;
67+ } , [ ] ) ;
68+
4969 // Get state from store
5070 const theme = useTheme ( ) ;
5171 const setTheme = useAppStore ( ( state ) => state . setTheme ) ;
@@ -171,7 +191,7 @@ function AppContent() {
171191 { activeNav === 'spaces' && < SpacesPage /> }
172192 { activeNav === 'featuresets' && < FeatureSetsPage /> }
173193 { activeNav === 'clients' && < ClientsPage /> }
174- { activeNav === 'settings' && < SettingsView /> }
194+ { activeNav === 'settings' && < SettingsPage /> }
175195 </ div >
176196 </ AppShell >
177197 ) ;
@@ -425,128 +445,4 @@ function DashboardView() {
425445 ) ;
426446}
427447
428- function SettingsView ( ) {
429- const theme = useTheme ( ) ;
430- const setTheme = useAppStore ( ( state ) => state . setTheme ) ;
431- const [ logsPath , setLogsPath ] = useState < string > ( '' ) ;
432- const [ openingLogs , setOpeningLogs ] = useState ( false ) ;
433-
434- // Load logs path on mount
435- useEffect ( ( ) => {
436- const loadLogsPath = async ( ) => {
437- try {
438- const { invoke } = await import ( '@tauri-apps/api/core' ) ;
439- const path = await invoke < string > ( 'get_logs_path' ) ;
440- setLogsPath ( path ) ;
441- } catch ( error ) {
442- console . error ( 'Failed to get logs path:' , error ) ;
443- }
444- } ;
445- loadLogsPath ( ) ;
446- } , [ ] ) ;
447-
448- const handleOpenLogs = async ( ) => {
449- setOpeningLogs ( true ) ;
450- try {
451- const { invoke } = await import ( '@tauri-apps/api/core' ) ;
452- await invoke ( 'open_logs_folder' ) ;
453- } catch ( error ) {
454- console . error ( 'Failed to open logs folder:' , error ) ;
455- } finally {
456- setOpeningLogs ( false ) ;
457- }
458- } ;
459-
460- return (
461- < div className = "space-y-6" >
462- < div >
463- < h1 className = "text-2xl font-bold" > Settings</ h1 >
464- < p className = "text-[rgb(var(--muted))]" > Configure McpMux preferences.</ p >
465- </ div >
466-
467- < Card >
468- < CardHeader >
469- < CardTitle > Appearance</ CardTitle >
470- < CardDescription > Customize the look and feel of McpMux.</ CardDescription >
471- </ CardHeader >
472- < CardContent >
473- < div className = "space-y-4" >
474- < div >
475- < label className = "text-sm font-medium" > Theme</ label >
476- < div className = "flex gap-2 mt-2" data-testid = "theme-buttons" >
477- < Button
478- variant = { theme === 'light' ? 'primary' : 'secondary' }
479- size = "sm"
480- onClick = { ( ) => setTheme ( 'light' ) }
481- data-testid = "theme-light-btn"
482- >
483- < Sun className = "h-4 w-4 mr-2" />
484- Light
485- </ Button >
486- < Button
487- variant = { theme === 'dark' ? 'primary' : 'secondary' }
488- size = "sm"
489- onClick = { ( ) => setTheme ( 'dark' ) }
490- data-testid = "theme-dark-btn"
491- >
492- < Moon className = "h-4 w-4 mr-2" />
493- Dark
494- </ Button >
495- < Button
496- variant = { theme === 'system' ? 'primary' : 'secondary' }
497- size = "sm"
498- onClick = { ( ) => setTheme ( 'system' ) }
499- data-testid = "theme-system-btn"
500- >
501- < Monitor className = "h-4 w-4 mr-2" />
502- System
503- </ Button >
504- </ div >
505- </ div >
506- </ div >
507- </ CardContent >
508- </ Card >
509-
510- < Card >
511- < CardHeader >
512- < CardTitle className = "flex items-center gap-2" >
513- < FileText className = "h-5 w-5" />
514- Logs
515- </ CardTitle >
516- < CardDescription > View application logs for debugging and troubleshooting.</ CardDescription >
517- </ CardHeader >
518- < CardContent >
519- < div className = "space-y-4" >
520- < div >
521- < label className = "text-sm font-medium" > Log Files Location</ label >
522- < p className = "text-sm text-[rgb(var(--muted))] mt-1 font-mono bg-surface-secondary rounded px-2 py-1" data-testid = "logs-path" >
523- { logsPath || 'Loading...' }
524- </ p >
525- </ div >
526- < div className = "flex items-center gap-2" >
527- < Button
528- variant = "secondary"
529- size = "sm"
530- onClick = { handleOpenLogs }
531- disabled = { openingLogs }
532- data-testid = "open-logs-btn"
533- >
534- { openingLogs ? (
535- < Loader2 className = "h-4 w-4 mr-2 animate-spin" />
536- ) : (
537- < FolderOpen className = "h-4 w-4 mr-2" />
538- ) }
539- Open Logs Folder
540- </ Button >
541- </ div >
542- < p className = "text-xs text-[rgb(var(--muted))]" >
543- Logs are rotated daily. Each file contains detailed debug information including thread IDs and source locations.
544- </ p >
545- </ div >
546- </ CardContent >
547- </ Card >
548- </ div >
549- ) ;
550- }
551-
552448export default App ;
0 commit comments