import { useEffect, useState, useRef } from "react"; import { Clock4 } from "lucide-react"; import { useTranslation } from "@termix/plugin-sdk/frontend"; import { registerWidget } from "./WidgetRegistry"; import type { TermixUptimeConfig, WidgetComponentProps } from "../types.js"; import { GRID_SIZE } from "../types.js"; import { WidgetTitle, getUptime, runVisibleInterval, } from "@termix/plugin-sdk/ui"; function formatUptime(seconds: number): { days: number; hours: number; minutes: number; secs: number; } { const days = Math.floor(seconds / 86400); const hours = Math.floor((seconds % 86400) / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = Math.floor(seconds % 60); return { days, hours, minutes, secs }; } function TermixUptimeWidget({ widget, config, }: WidgetComponentProps) { const { t } = useTranslation(); const { showDetailed } = config; const [seconds, setSeconds] = useState(null); const [error, setError] = useState(false); const baseRef = useRef(null); const startRef = useRef(Date.now()); useEffect(() => { getUptime() .then((info) => { baseRef.current = info.uptimeSeconds; startRef.current = Date.now(); setSeconds(info.uptimeSeconds); }) .catch(() => setError(true)); return runVisibleInterval(() => { if (baseRef.current !== null) { const elapsed = (Date.now() - startRef.current) / 1000; setSeconds(Math.floor(baseRef.current + elapsed)); } }, 1000); }, []); if (error) { return (
{t("homepage.uptimeUnavailable")}
); } if (seconds === null) { return (
{t("common.loading")}
); } const { days, hours, minutes, secs } = formatUptime(seconds); const accent = getComputedStyle(document.documentElement) .getPropertyValue("--accent-brand") .trim() || "#f59145"; return (
} />
{days > 0 && ( {days} d )} {String(hours).padStart(2, "0")} h {String(minutes).padStart(2, "0")} m {showDetailed && ( {String(secs).padStart(2, "0")} s )}
{t("homepage.uptimeLabel")}
); } registerWidget({ id: "termix_uptime", name: "Termix Uptime", description: "Shows how long the Termix server has been running", category: "system", icon: , defaultConfig: { showDetailed: false }, defaultSize: { w: GRID_SIZE * 8, h: GRID_SIZE * 4 }, minSize: { w: GRID_SIZE * 3, h: GRID_SIZE * 2 }, component: TermixUptimeWidget, }); export { TermixUptimeWidget };