Replace inline frontend styles with makeStyles and design tokens

This commit is contained in:
2026-04-19 12:04:24 +02:00
parent 91269448d0
commit d99d6bd119
16 changed files with 344 additions and 265 deletions

View File

@@ -9,6 +9,7 @@
* remains fast even when a jail contains thousands of banned IPs.
*/
import { useMemo } from "react";
import {
Badge,
Button,
@@ -102,10 +103,19 @@ const useStyles = makeStyles({
alignItems: "center",
gap: tokens.spacingHorizontalXS,
},
rowsPerPageDropdown: {
minWidth: "80px",
},
mono: {
fontFamily: "Consolas, 'Courier New', monospace",
fontFamily: tokens.fontFamilyMonospace,
fontSize: tokens.fontSizeBase200,
},
emptyText: {
color: tokens.colorNeutralForeground3,
},
emptyValue: {
color: tokens.colorNeutralForeground4,
},
});
// ---------------------------------------------------------------------------
@@ -118,64 +128,6 @@ interface BanRow {
onUnban: (ip: string) => Promise<void>;
}
const columns: TableColumnDefinition<BanRow>[] = [
createTableColumn<BanRow>({
columnId: "ip",
renderHeaderCell: () => "IP Address",
renderCell: ({ ban }) => (
<Text
style={{
fontFamily: "Consolas, 'Courier New', monospace",
fontSize: tokens.fontSizeBase200,
}}
>
{ban.ip}
</Text>
),
}),
createTableColumn<BanRow>({
columnId: "country",
renderHeaderCell: () => "Country",
renderCell: ({ ban }) =>
ban.country ? (
<Text size={200}>{ban.country}</Text>
) : (
<Text size={200} style={{ color: tokens.colorNeutralForeground4 }}>
</Text>
),
}),
createTableColumn<BanRow>({
columnId: "banned_at",
renderHeaderCell: () => "Banned At",
renderCell: ({ ban }) => (
<Text size={200}>{ban.banned_at ? formatTimestamp(ban.banned_at) : "—"}</Text>
),
}),
createTableColumn<BanRow>({
columnId: "expires_at",
renderHeaderCell: () => "Expires At",
renderCell: ({ ban }) => (
<Text size={200}>{ban.expires_at ? formatTimestamp(ban.expires_at) : "—"}</Text>
),
}),
createTableColumn<BanRow>({
columnId: "actions",
renderHeaderCell: () => "",
renderCell: ({ ban, onUnban }) => (
<Tooltip content={`Unban ${ban.ip}`} relationship="label">
<Button
size="small"
appearance="subtle"
icon={<DismissRegular />}
onClick={() => { void onUnban(ban.ip); }}
aria-label={`Unban ${ban.ip}`}
/>
</Tooltip>
),
}),
];
// ---------------------------------------------------------------------------
// Props
// ---------------------------------------------------------------------------
@@ -224,6 +176,58 @@ export function BannedIpsSection({
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const columns: TableColumnDefinition<BanRow>[] = useMemo(
() => [
createTableColumn<BanRow>({
columnId: "ip",
renderHeaderCell: () => "IP Address",
renderCell: ({ ban }) => <Text className={styles.mono}>{ban.ip}</Text>,
}),
createTableColumn<BanRow>({
columnId: "country",
renderHeaderCell: () => "Country",
renderCell: ({ ban }) =>
ban.country ? (
<Text size={200}>{ban.country}</Text>
) : (
<Text size={200} className={styles.emptyValue}>
</Text>
),
}),
createTableColumn<BanRow>({
columnId: "banned_at",
renderHeaderCell: () => "Banned At",
renderCell: ({ ban }) => (
<Text size={200}>{ban.banned_at ? formatTimestamp(ban.banned_at) : "—"}</Text>
),
}),
createTableColumn<BanRow>({
columnId: "expires_at",
renderHeaderCell: () => "Expires At",
renderCell: ({ ban }) => (
<Text size={200}>{ban.expires_at ? formatTimestamp(ban.expires_at) : "—"}</Text>
),
}),
createTableColumn<BanRow>({
columnId: "actions",
renderHeaderCell: () => "",
renderCell: ({ ban, onUnban }) => (
<Tooltip content={`Unban ${ban.ip}`} relationship="label">
<Button
size="small"
appearance="subtle"
icon={<DismissRegular />}
onClick={() => { void onUnban(ban.ip); }}
aria-label={`Unban ${ban.ip}`}
/>
</Tooltip>
),
}),
],
[styles],
);
const rows: BanRow[] = items.map((ban) => ({
ban,
onUnban,
@@ -286,7 +290,7 @@ export function BannedIpsSection({
</div>
) : items.length === 0 ? (
<div className={styles.centred}>
<Text size={200} style={{ color: tokens.colorNeutralForeground3 }}>
<Text size={200} className={styles.emptyText}>
No IPs currently banned in this jail.
</Text>
</div>
@@ -334,7 +338,7 @@ export function BannedIpsSection({
onPageChange(1);
}
}}
style={{ minWidth: "80px" }}
className={styles.rowsPerPageDropdown}
>
{PAGE_SIZE_OPTIONS.map((n) => (
<Option key={n} value={String(n)}>