import React, { useEffect, useState } from "react"; import { Auth } from "@/ui/Desktop/Authentication/Auth.tsx"; import { UpdateLog } from "@/ui/Desktop/Apps/Dashboard/Apps/UpdateLog.tsx"; import { AlertManager } from "@/ui/Desktop/Apps/Dashboard/Apps/Alerts/AlertManager.tsx"; import { Button } from "@/components/ui/button.tsx"; import { getUserInfo, getDatabaseHealth, getCookie, getUptime, getVersionInfo, getSSHHosts, getTunnelStatuses, getCredentials, getRecentActivity, resetRecentActivity, getServerMetricsById, type RecentActivityItem, } from "@/ui/main-axios.ts"; import { useSidebar } from "@/components/ui/sidebar.tsx"; import { Separator } from "@/components/ui/separator.tsx"; import { useTabs } from "@/ui/Desktop/Navigation/Tabs/TabContext.tsx"; import { ChartLine, Clock, Database, FastForward, History, Key, Network, Server, UserPlus, Settings, User, } from "lucide-react"; import { Status } from "@/components/ui/shadcn-io/status"; import { BsLightning } from "react-icons/bs"; interface DashboardProps { onSelectView: (view: string) => void; isAuthenticated: boolean; authLoading: boolean; onAuthSuccess: (authData: { isAdmin: boolean; username: string | null; userId: string | null; }) => void; isTopbarOpen: boolean; } export function Dashboard({ isAuthenticated, authLoading, onAuthSuccess, isTopbarOpen, onSelectView, }: DashboardProps): React.ReactElement { const [loggedIn, setLoggedIn] = useState(isAuthenticated); const [isAdmin, setIsAdmin] = useState(false); const [, setUsername] = useState(null); const [userId, setUserId] = useState(null); const [dbError, setDbError] = useState(null); // Dashboard data state const [uptime, setUptime] = useState("0d 0h 0m"); const [versionStatus, setVersionStatus] = useState< "up_to_date" | "requires_update" >("up_to_date"); const [versionText, setVersionText] = useState("v1.8.0"); const [dbHealth, setDbHealth] = useState<"healthy" | "error">("healthy"); const [totalServers, setTotalServers] = useState(0); const [totalTunnels, setTotalTunnels] = useState(0); const [totalCredentials, setTotalCredentials] = useState(0); const [recentActivity, setRecentActivity] = useState( [], ); const [serverStats, setServerStats] = useState< Array<{ id: number; name: string; cpu: number | null; ram: number | null }> >([]); const { addTab, setCurrentTab, tabs: tabList } = useTabs(); let sidebarState: "expanded" | "collapsed" = "expanded"; try { const sidebar = useSidebar(); sidebarState = sidebar.state; } catch {} const topMarginPx = isTopbarOpen ? 74 : 26; const leftMarginPx = sidebarState === "collapsed" ? 26 : 8; const bottomMarginPx = 8; useEffect(() => { setLoggedIn(isAuthenticated); }, [isAuthenticated]); useEffect(() => { if (isAuthenticated) { if (getCookie("jwt")) { getUserInfo() .then((meRes) => { setIsAdmin(!!meRes.is_admin); setUsername(meRes.username || null); setUserId(meRes.userId || null); setDbError(null); }) .catch((err) => { setIsAdmin(false); setUsername(null); setUserId(null); const errorCode = err?.response?.data?.code; if (errorCode === "SESSION_EXPIRED") { console.warn("Session expired - please log in again"); setDbError("Session expired - please log in again"); } else { setDbError(null); } }); getDatabaseHealth() .then(() => { setDbError(null); }) .catch((err) => { if (err?.response?.data?.error?.includes("Database")) { setDbError( "Could not connect to the database. Please try again later.", ); } }); } } }, [isAuthenticated]); // Fetch dashboard data useEffect(() => { if (!loggedIn) return; const fetchDashboardData = async () => { try { // Fetch uptime const uptimeInfo = await getUptime(); setUptime(uptimeInfo.formatted); // Fetch version info const versionInfo = await getVersionInfo(); setVersionText(`v${versionInfo.localVersion}`); setVersionStatus(versionInfo.status || "up_to_date"); // Fetch database health try { await getDatabaseHealth(); setDbHealth("healthy"); } catch { setDbHealth("error"); } // Fetch total counts const hosts = await getSSHHosts(); setTotalServers(hosts.length); // Count total tunnels across all hosts let totalTunnelsCount = 0; for (const host of hosts) { if (host.tunnelConnections) { try { const tunnelConnections = JSON.parse(host.tunnelConnections); if (Array.isArray(tunnelConnections)) { totalTunnelsCount += tunnelConnections.length; } } catch { // Ignore parse errors } } } setTotalTunnels(totalTunnelsCount); const credentials = await getCredentials(); setTotalCredentials(credentials.length); // Fetch recent activity (35 items) const activity = await getRecentActivity(35); setRecentActivity(activity); // Fetch server stats for first 5 servers const serversWithStats = await Promise.all( hosts.slice(0, 5).map(async (host: { id: number; name: string }) => { try { const metrics = await getServerMetricsById(host.id); return { id: host.id, name: host.name || `Host ${host.id}`, cpu: metrics.cpu.percent, ram: metrics.memory.percent, }; } catch { return { id: host.id, name: host.name || `Host ${host.id}`, cpu: null, ram: null, }; } }), ); setServerStats(serversWithStats); } catch (error) { console.error("Failed to fetch dashboard data:", error); } }; fetchDashboardData(); // Refresh every 30 seconds const interval = setInterval(fetchDashboardData, 30000); return () => clearInterval(interval); }, [loggedIn]); // Handler for resetting recent activity const handleResetActivity = async () => { try { await resetRecentActivity(); setRecentActivity([]); } catch (error) { console.error("Failed to reset activity:", error); } }; // Handler for opening a recent activity item const handleActivityClick = (item: RecentActivityItem) => { // Find the host and open appropriate tab getSSHHosts().then((hosts) => { const host = hosts.find((h: { id: number }) => h.id === item.hostId); if (!host) return; if (item.type === "terminal") { addTab({ type: "terminal", title: item.hostName, hostConfig: host, }); } else if (item.type === "file_manager") { addTab({ type: "file_manager", title: item.hostName, hostConfig: host, }); } }); }; // Quick Actions handlers const handleAddHost = () => { const sshManagerTab = tabList.find((t) => t.type === "ssh_manager"); if (sshManagerTab) { setCurrentTab(sshManagerTab.id); } else { const id = addTab({ type: "ssh_manager", title: "Host Manager", initialTab: "add_host", }); setCurrentTab(id); } }; const handleAddCredential = () => { const sshManagerTab = tabList.find((t) => t.type === "ssh_manager"); if (sshManagerTab) { setCurrentTab(sshManagerTab.id); } else { const id = addTab({ type: "ssh_manager", title: "Host Manager", initialTab: "add_credential", }); setCurrentTab(id); } }; const handleOpenAdminSettings = () => { const adminTab = tabList.find((t) => t.type === "admin"); if (adminTab) { setCurrentTab(adminTab.id); } else { const id = addTab({ type: "admin", title: "Admin Settings" }); setCurrentTab(id); } }; const handleOpenUserProfile = () => { const userProfileTab = tabList.find((t) => t.type === "user_profile"); if (userProfileTab) { setCurrentTab(userProfileTab.id); } else { const id = addTab({ type: "user_profile", title: "User Profile" }); setCurrentTab(id); } }; return ( <> {!loggedIn ? (
) : (
Dashboard

Server Overview

Version

{versionText}

Uptime

{uptime}

Database

{dbHealth}

Total Servers

{totalServers}

Total Tunnels

{totalTunnels}

Total Credentials

{totalCredentials}

Recent Activity

{recentActivity.length === 0 ? (

No recent activity

) : ( recentActivity.map((item) => ( )) )}

Quick Actions

{isAdmin && ( )}

Server Stats

{serverStats.length === 0 ? (

No server data available

) : ( serverStats.map((server) => ( )) )}
)} ); }