Files
BanGUI/frontend/src/pages/jail/JailInfoSection.tsx

147 lines
4.7 KiB
TypeScript

import { useState } from "react";
import { useNavigate } from "react-router-dom";
import {
Badge,
Button,
MessageBar,
MessageBarBody,
Text,
} from "@fluentui/react-components";
import {
ArrowClockwiseRegular,
ArrowSyncRegular,
PauseRegular,
PlayRegular,
StopRegular,
} from "@fluentui/react-icons";
import { useCommonSectionStyles } from "../../components/commonStyles";
import { useJailDetailPageStyles } from "./jailDetailPageStyles";
import type { Jail } from "../../types/jail";
interface JailInfoProps {
jail: Jail;
onRefresh: () => void;
onStart: () => Promise<void>;
onStop: () => Promise<void>;
onSetIdle: (on: boolean) => Promise<void>;
onReload: () => Promise<void>;
}
export function JailInfoSection({ jail, onRefresh, onStart, onStop, onSetIdle, onReload }: JailInfoProps): React.JSX.Element {
const styles = useJailDetailPageStyles();
const sectionStyles = useCommonSectionStyles();
const navigate = useNavigate();
const [ctrlError, setCtrlError] = useState<string | null>(null);
const handle =
(fn: () => Promise<unknown>, postNavigate = false) =>
(): void => {
setCtrlError(null);
fn()
.then(() => {
if (postNavigate) {
navigate("/jails");
} else {
onRefresh();
}
})
.catch((err: unknown) => {
const msg = err instanceof Error ? err.message : String(err);
setCtrlError(msg);
});
};
return (
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<div className={styles.headerRow}>
<Text size={600} weight="semibold" style={{ fontFamily: "Consolas, 'Courier New', monospace" }}>
{jail.name}
</Text>
{jail.running ? (
jail.idle ? (
<Badge appearance="filled" color="warning">idle</Badge>
) : (
<Badge appearance="filled" color="success">running</Badge>
)
) : (
<Badge appearance="filled" color="danger">stopped</Badge>
)}
</div>
<Button
size="small"
appearance="subtle"
icon={<ArrowClockwiseRegular />}
onClick={onRefresh}
aria-label="Refresh"
/>
</div>
{ctrlError && (
<MessageBar intent="error">
<MessageBarBody>{ctrlError}</MessageBarBody>
</MessageBar>
)}
<div className={styles.controlRow}>
{jail.running ? (
<Button appearance="secondary" icon={<StopRegular />} onClick={handle(onStop)}>
Stop
</Button>
) : (
<Button appearance="primary" icon={<PlayRegular />} onClick={handle(onStart)}>
Start
</Button>
)}
<Button
appearance="outline"
icon={<PauseRegular />}
onClick={handle(() => onSetIdle(!jail.idle))}
disabled={!jail.running}
>
{jail.idle ? "Resume" : "Set Idle"}
</Button>
<Button appearance="outline" icon={<ArrowSyncRegular />} onClick={handle(onReload)}>
Reload
</Button>
</div>
{jail.status && (
<div className={styles.grid} style={{ marginTop: "var(--spacingVerticalS)" }}>
<Text className={styles.label}>Currently banned:</Text>
<Text>{String(jail.status.currently_banned)}</Text>
<Text className={styles.label}>Total banned:</Text>
<Text>{String(jail.status.total_banned)}</Text>
<Text className={styles.label}>Currently failed:</Text>
<Text>{String(jail.status.currently_failed)}</Text>
<Text className={styles.label}>Total failed:</Text>
<Text>{String(jail.status.total_failed)}</Text>
</div>
)}
<div className={styles.grid} style={{ marginTop: "var(--spacingVerticalS)" }}>
<Text className={styles.label}>Backend:</Text>
<Text className={styles.mono}>{jail.backend}</Text>
<Text className={styles.label}>Find time:</Text>
<Text>{String(jail.find_time)}</Text>
<Text className={styles.label}>Ban time:</Text>
<Text>{String(jail.ban_time)}</Text>
<Text className={styles.label}>Max retry:</Text>
<Text>{String(jail.max_retry)}</Text>
{jail.date_pattern && (
<>
<Text className={styles.label}>Date pattern:</Text>
<Text className={styles.mono}>{jail.date_pattern}</Text>
</>
)}
{jail.log_encoding && (
<>
<Text className={styles.label}>Log encoding:</Text>
<Text className={styles.mono}>{jail.log_encoding}</Text>
</>
)}
</div>
</div>
);
}