Files
BanGUI/frontend/src/pages/ConfigPage.tsx

112 lines
3.1 KiB
TypeScript

/**
* Configuration page — fail2ban jail and server configuration editor.
*
* Renders the top-level tab bar and delegates rendering to the appropriate
* tab component from {@link ../components/config}.
*
* Tabs:
* Jails — per-jail config accordion with inline editing
* Filters — structured filter.d form editor
* Actions — structured action.d form editor
* Server — server-level settings, map thresholds, service health + log viewer
* Regex Tester — live pattern tester
* Export — raw file editors for jail, filter, and action files
*/
import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import { Tab, TabList, Text, makeStyles, tokens } from "@fluentui/react-components";
import {
ActionsTab,
FiltersTab,
JailsTab,
RegexTesterTab,
ServerTab,
} from "../components/config";
// ---------------------------------------------------------------------------
// Page-level styles (tab shell only — component styles live in configStyles.ts)
// ---------------------------------------------------------------------------
const useStyles = makeStyles({
page: {
padding: tokens.spacingVerticalXXL,
maxWidth: "1100px",
},
header: {
marginBottom: tokens.spacingVerticalL,
},
tabContent: {
marginTop: tokens.spacingVerticalL,
animationName: "fadeInUp",
animationDuration: tokens.durationNormal,
animationTimingFunction: tokens.curveDecelerateMid,
animationFillMode: "both",
},
infoText: {
color: tokens.colorNeutralForeground3,
fontStyle: "italic",
},
});
type TabValue =
| "jails"
| "filters"
| "actions"
| "server"
| "regex";
export function ConfigPage(): React.JSX.Element {
const styles = useStyles();
const location = useLocation();
const [tab, setTab] = useState<TabValue>("jails");
useEffect(() => {
const state = location.state as { tab?: string; jail?: string } | null;
if (state?.tab === "jails") {
setTab("jails");
}
}, [location.state]);
return (
<div className={styles.page}>
<div className={styles.header}>
<Text as="h1" size={700} weight="semibold" block>
Configuration
</Text>
<Text as="p" size={300} className={styles.infoText}>
Inspect and edit fail2ban jail configuration, global settings, and
server parameters.
</Text>
</div>
<TabList
selectedValue={tab}
onTabSelect={(_e, d) => {
setTab(d.value as TabValue);
}}
>
<Tab value="jails">Jails</Tab>
<Tab value="filters">Filters</Tab>
<Tab value="actions">Actions</Tab>
<Tab value="server">Server</Tab>
<Tab value="regex">Regex Tester</Tab>
</TabList>
<div className={styles.tabContent} key={tab}>
{tab === "jails" && (
<JailsTab
initialJail={(location.state as { jail?: string } | null)?.jail}
/>
)}
{tab === "filters" && <FiltersTab />}
{tab === "actions" && <ActionsTab />}
{tab === "server" && <ServerTab />}
{tab === "regex" && <RegexTesterTab />}
</div>
</div>
);
}