/** * `ServerStatusBar` component. * * Displays a persistent bar at the top of the dashboard showing the * fail2ban server health snapshot: connectivity status, version, active * jail count, and aggregated ban/failure totals. * * Polls `GET /api/dashboard/status` every 30 seconds and on window focus * via the {@link useServerStatus} hook. */ import { Badge, Button, makeStyles, Spinner, Text, tokens, Tooltip, } from "@fluentui/react-components"; import { ArrowClockwiseRegular, ShieldRegular } from "@fluentui/react-icons"; import { useServerStatus } from "../hooks/useServerStatus"; // --------------------------------------------------------------------------- // Styles // --------------------------------------------------------------------------- const useStyles = makeStyles({ bar: { display: "flex", alignItems: "center", gap: tokens.spacingHorizontalL, padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalL}`, backgroundColor: tokens.colorNeutralBackground1, borderRadius: tokens.borderRadiusMedium, borderTopWidth: "1px", borderTopStyle: "solid", borderTopColor: tokens.colorNeutralStroke2, borderRightWidth: "1px", borderRightStyle: "solid", borderRightColor: tokens.colorNeutralStroke2, borderBottomWidth: "1px", borderBottomStyle: "solid", borderBottomColor: tokens.colorNeutralStroke2, borderLeftWidth: "1px", borderLeftStyle: "solid", borderLeftColor: tokens.colorNeutralStroke2, marginBottom: tokens.spacingVerticalL, flexWrap: "wrap", }, statusGroup: { display: "flex", alignItems: "center", gap: tokens.spacingHorizontalS, }, statGroup: { display: "flex", alignItems: "center", gap: tokens.spacingHorizontalXS, }, statValue: { fontVariantNumeric: "tabular-nums", fontWeight: 600, }, spacer: { flexGrow: 1, }, errorText: { color: tokens.colorPaletteRedForeground1, fontSize: "12px", }, }); // --------------------------------------------------------------------------- // Component // --------------------------------------------------------------------------- /** * Persistent bar displaying fail2ban server health. * * Render this at the top of the dashboard page (and any page that should * show live server status). */ export function ServerStatusBar(): React.JSX.Element { const styles = useStyles(); const { status, banguiVersion, loading, error, refresh } = useServerStatus(); return (
{/* ---------------------------------------------------------------- */} {/* Online / Offline badge */} {/* ---------------------------------------------------------------- */}
{loading && !status ? ( ) : ( {status?.online ? "Online" : "Offline"} )}
{/* ---------------------------------------------------------------- */} {/* Version */} {/* ---------------------------------------------------------------- */} {status?.version != null && ( v{status.version} )} {banguiVersion != null && ( BanGUI v{banguiVersion} )} {/* ---------------------------------------------------------------- */} {/* Stats (only when online) */} {/* ---------------------------------------------------------------- */} {status?.online === true && ( <>
Jails: {status.active_jails}
Bans: {status.total_bans}
Failed Attempts: {status.total_failures}
)} {/* ---------------------------------------------------------------- */} {/* Error message */} {/* ---------------------------------------------------------------- */} {error != null && ( {error} )}
{/* ---------------------------------------------------------------- */} {/* Refresh button */} {/* ---------------------------------------------------------------- */}
); }