Backend (tasks 1.1, 1.5–1.8): - pyproject.toml with FastAPI, Pydantic v2, aiosqlite, APScheduler 3.x, structlog, bcrypt; ruff + mypy strict configured - Pydantic Settings (BANGUI_ prefix env vars, fail-fast validation) - SQLite schema: settings, sessions, blocklist_sources, import_log; WAL mode + foreign keys; idempotent init_db() - FastAPI app factory with lifespan (DB, aiohttp session, scheduler), CORS, unhandled-exception handler, GET /api/health - Fail2BanClient: async Unix-socket wrapper using run_in_executor, custom error types, async context manager - Utility modules: ip_utils, time_utils, constants - 47 tests; ruff 0 errors; mypy --strict 0 errors Frontend (tasks 1.2–1.4): - Vite + React 18 + TypeScript strict; Fluent UI v9; ESLint + Prettier - Custom brand theme (#0F6CBD, WCAG AA contrast) with light/dark variants - Typed fetch API client (ApiError, get/post/put/del) + endpoints constants - tsc --noEmit 0 errors
48 lines
1.2 KiB
TypeScript
48 lines
1.2 KiB
TypeScript
/**
|
|
* BanGUI Fluent UI custom theme.
|
|
*
|
|
* The primary brand colour ramp is built around #0F6CBD (a deep, professional blue).
|
|
* This colour has a contrast ratio of ~5.4:1 against white, satisfying WCAG 2.1 AA
|
|
* requirements for both text and large UI elements.
|
|
*
|
|
* Both `lightTheme` and `darkTheme` share the same brand ramp so all semantic
|
|
* colour slots stay consistent when the user switches modes.
|
|
*/
|
|
|
|
import {
|
|
createDarkTheme,
|
|
createLightTheme,
|
|
type BrandVariants,
|
|
type Theme,
|
|
} from "@fluentui/react-components";
|
|
|
|
/**
|
|
* BanGUI brand colour ramp — 16 stops from 10 (darkest) to 160 (lightest).
|
|
*
|
|
* Primary stop (80): #0F6CBD — contrast ratio ≈ 5.4:1 against white.
|
|
*/
|
|
const banGuiBrand: BrandVariants = {
|
|
10: "#020D1A",
|
|
20: "#041B32",
|
|
30: "#072B50",
|
|
40: "#0A3C6E",
|
|
50: "#0C4E8A",
|
|
60: "#0E5FA7",
|
|
70: "#1169BA",
|
|
80: "#0F6CBD" /* PRIMARY — passes WCAG AA */,
|
|
90: "#2C81CC",
|
|
100: "#4A96D8",
|
|
110: "#6CADE3",
|
|
120: "#91C5EC",
|
|
130: "#B5D9F3",
|
|
140: "#D2EAF8",
|
|
150: "#E8F4FB",
|
|
160: "#F3F9FD",
|
|
};
|
|
|
|
/** Light theme using the BanGUI brand palette. */
|
|
export const lightTheme: Theme = createLightTheme(banGuiBrand);
|
|
|
|
/** Dark theme using the BanGUI brand palette. */
|
|
export const darkTheme: Theme = createDarkTheme(banGuiBrand);
|