Files
BanGUI/frontend/src/hooks/useImportLog.ts

64 lines
1.7 KiB
TypeScript

/**
* React hook for loading paginated blocklist import log entries.
*/
import { useCallback, useEffect, useRef, useState } from "react";
import { fetchImportLog } from "../api/blocklist";
import { handleFetchError } from "../utils/fetchError";
import type { ImportLogListResponse } from "../types/blocklist";
export interface UseImportLogReturn {
data: ImportLogListResponse | null;
loading: boolean;
error: string | null;
page: number;
setPage: (n: number) => void;
refresh: () => void;
}
/**
* Fetch the paginated import log with optional source filter.
*/
export function useImportLog(
sourceId?: number,
pageSize = 50,
): UseImportLogReturn {
const [data, setData] = useState<ImportLogListResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [page, setPage] = useState(1);
const abortRef = useRef<AbortController | null>(null);
const load = useCallback((): void => {
abortRef.current?.abort();
const ctrl = new AbortController();
abortRef.current = ctrl;
setLoading(true);
setError(null);
fetchImportLog(page, pageSize, sourceId)
.then((result) => {
if (!ctrl.signal.aborted) {
setData(result);
setLoading(false);
}
})
.catch((err: unknown) => {
if (!ctrl.signal.aborted) {
handleFetchError(err, setError, "Failed to load import log");
setLoading(false);
}
});
}, [page, pageSize, sourceId]);
useEffect(() => {
load();
return (): void => {
abortRef.current?.abort();
};
}, [load]);
return { data, loading, error, page, setPage, refresh: load };
}