import { Link, Stack, useSearchParams } from "expo-router"; import { View, Text, SafeAreaView, ScrollView } from "react-native"; import { NodeResource, useNode } from "../../../hooks/useNode"; import Icon from "@expo/vector-icons/Feather"; import tw from "twrnc"; import { formatBytes, formatPercentage } from "../../../lib/helper/format"; import { useEffect, useMemo } from "react"; interface ResourceListItemProps { type: "LXC" | "QEMU"; resource: NodeResource; } export function ResourceListItem({ type, resource }: ResourceListItemProps) { return ( {type === "LXC" ? ( ) : ( )} {resource.vmid}: {resource.name} CPUs: {resource.cpus} MEM: {formatBytes(resource.maxmem)} DISK: {formatBytes(resource.maxdisk)} ); } interface ProgressBarProps { label: string; value: number; max: number; formatFn?: (input: number) => string; } export function ProgressBar({ label, value, max, formatFn }: ProgressBarProps) { const percentage = formatPercentage(value / max); return ( {label} ({percentage}) {formatFn && ( {formatFn(value)}/{formatFn(max)} )} ); } interface GaugeProps { label: string; value: string; } export function Gauge({ label, value }: GaugeProps) { return ( {label} {value} ); } export default function NodePage() { const { node: nodeName } = useSearchParams<{ node: string }>(); const node = useNode(nodeName); const sortedLXCs = useMemo(() => { if (!node.lxc.isSuccess) return []; return node.lxc.data.sort((a, b) => a.vmid - b.vmid); }, [node.lxc.data]); const sortedVMs = useMemo(() => { if (!node.qemu.isSuccess) return []; return node.qemu.data.sort((a, b) => a.vmid - b.vmid); }, [node.qemu.data]); return ( {nodeName} {node.status.isSuccess && ( {node.status.data.pveversion} {node.status.data.kversion} )} {node.rdd.isSuccess && ( )} LXC Containers {sortedLXCs.map((lxc) => ( ))} Virtual Machines {sortedVMs.map((vm) => ( ))} ); }