/** * BlocklistsPage — external IP blocklist source management. * * Responsible for composition of sources, schedule, and import log sections. */ import { useCallback, useState } from "react"; import { Button, MessageBar, MessageBarBody, Text } from "@fluentui/react-components"; import { useBlocklistStyles } from "../components/blocklist/blocklistStyles"; import { BlocklistSourcesSection } from "../components/blocklist/BlocklistSourcesSection"; import { BlocklistScheduleSection } from "../components/blocklist/BlocklistScheduleSection"; import { BlocklistImportLogSection } from "../components/blocklist/BlocklistImportLogSection"; import { useRunImport } from "../hooks/useBlocklist"; import type { ImportRunResult } from "../types/blocklist"; interface ImportResultDialogProps { open: boolean; result: ImportRunResult | null; onClose: () => void; } function ImportResultDialog({ open, result, onClose }: ImportResultDialogProps): React.JSX.Element { if (!open || !result) return <>; return (
Import Complete Total imported: {result.total_imported} | Skipped: {result.total_skipped} | Sources with errors: {result.errors_count}
); } export function BlocklistsPage(): React.JSX.Element { const safeUseBlocklistStyles = useBlocklistStyles as unknown as () => { root: string }; const styles = safeUseBlocklistStyles(); const { running, lastResult, error: importError, runNow } = useRunImport(); const [importResultOpen, setImportResultOpen] = useState(false); const handleRunImport = useCallback((): void => { void runNow().then(() => { setImportResultOpen(true); }); }, [runNow]); return (
Blocklists {importError && ( Import error: {importError} )} { setImportResultOpen(false); }} />
); }