import './index.css' import React, { Suspense, lazy, useEffect } from 'react' import ReactDOM from 'react-dom/client' import Home from './components/routes/home.tsx' import { ThemeProvider } from './components/theme-provider.tsx' import { $alerts, $authenticated, $updatedSystem, $systems, pb } from './lib/stores.ts' import { ModeToggle } from './components/mode-toggle.tsx' import { cn, isAdmin, updateAlerts, updateFavicon, updateRecordList, updateSystemList, } from './lib/utils.ts' import { buttonVariants } from './components/ui/button.tsx' import { DatabaseBackupIcon, GithubIcon, LockKeyholeIcon, LogOutIcon, LogsIcon, ServerIcon, UserIcon, UsersIcon, } from 'lucide-react' import { useStore } from '@nanostores/react' import { Toaster } from './components/ui/toaster.tsx' import { Logo } from './components/logo.tsx' import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, } from '@/components/ui/tooltip.tsx' import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenuLabel, } from './components/ui/dropdown-menu.tsx' import { AlertRecord, SystemRecord } from './types' import { $router, Link, navigate } from './components/router.tsx' import ServerDetail from './components/routes/system.tsx' // const ServerDetail = lazy(() => import('./components/routes/system.tsx')) const CommandPalette = lazy(() => import('./components/command-palette.tsx')) const LoginPage = lazy(() => import('./components/login/login.tsx')) const App = () => { const page = useStore($router) const authenticated = useStore($authenticated) const systems = useStore($systems) useEffect(() => { // change auth store on auth change pb.authStore.onChange(() => { $authenticated.set(pb.authStore.isValid) }) // get servers / alerts updateSystemList() updateAlerts() // subscribe to real time updates for systems / alerts pb.collection('systems').subscribe('*', (e) => { updateRecordList(e, $systems) $updatedSystem.set(e.record) }) pb.collection('alerts').subscribe('*', (e) => { updateRecordList(e, $alerts) }) return () => { pb.collection('systems').unsubscribe('*') pb.collection('alerts').unsubscribe('*') } }, []) // update favicon useEffect(() => { if (!authenticated || !systems.length) { updateFavicon('favicon.svg') } else { let up = false for (const system of systems) { if (system.status === 'down') { updateFavicon('favicon-red.svg') return () => updateFavicon('favicon.svg') } else if (system.status === 'up') { up = true } } updateFavicon(up ? 'favicon-green.svg' : 'favicon.svg') return () => updateFavicon('favicon.svg') } return () => { updateFavicon('favicon.svg') } }, [authenticated, systems]) if (!page) { return

404

} else if (page.path === '/') { return } else if (page.route === 'server') { return } } const Layout = () => { const authenticated = useStore($authenticated) if (!authenticated) { return ( ) } return ( <>
{ e.preventDefault() navigate('/') }} >

Github Repository

{pb.authStore.model?.email} {isAdmin() && ( <> Users Systems Logs Backups Auth providers )} pb.authStore.clear()}> Log out
) } ReactDOM.createRoot(document.getElementById('app')!).render( )