Refactor schedule functionality in frontend

- Extract schedule logic into custom useSchedule hook
- Update BlocklistScheduleSection to use the new hook
- Add tests for useSchedule hook
- Update documentation with task progress

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-23 09:40:19 +02:00
parent a87d892584
commit 9375430e02
5 changed files with 155 additions and 35 deletions

View File

@@ -2,7 +2,7 @@
* React hook for fetching and updating the blocklist import schedule.
*/
import { useCallback, useEffect, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { fetchSchedule, updateSchedule } from "../api/blocklist";
import { handleFetchError } from "../utils/fetchError";
import type { ScheduleConfig, ScheduleInfo } from "../types/blocklist";
@@ -12,6 +12,7 @@ export interface UseScheduleReturn {
loading: boolean;
error: string | null;
saveSchedule: (config: ScheduleConfig) => Promise<void>;
refresh: () => void;
}
/**
@@ -21,9 +22,13 @@ export function useSchedule(): UseScheduleReturn {
const [info, setInfo] = useState<ScheduleInfo | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const abortRef = useRef<AbortController | null>(null);
useEffect(() => {
const refresh = useCallback((): void => {
abortRef.current?.abort();
const controller = new AbortController();
abortRef.current = controller;
setLoading(true);
setError(null);
@@ -37,19 +42,24 @@ export function useSchedule(): UseScheduleReturn {
handleFetchError(err, setError, "Failed to load schedule");
})
.finally(() => {
if (controller.signal.aborted) return;
setLoading(false);
if (!controller.signal.aborted) {
setLoading(false);
}
});
}, []);
useEffect(() => {
refresh();
return (): void => {
controller.abort();
abortRef.current?.abort();
};
}, []);
}, [refresh]);
const saveSchedule = useCallback(async (config: ScheduleConfig): Promise<void> => {
const updated = await updateSchedule(config);
setInfo(updated);
}, []);
return { info, loading, error, saveSchedule };
return { info, loading, error, saveSchedule, refresh };
}