132 lines
3.0 KiB
TypeScript
132 lines
3.0 KiB
TypeScript
|
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||
|
|
|
||
|
|
import { memoirApi } from './api';
|
||
|
|
import { toChapterViewModels } from './mappers';
|
||
|
|
import { memoirKeys } from './query-keys';
|
||
|
|
import type { ExportPdfRequest, UpdateBookRequest } from './types';
|
||
|
|
|
||
|
|
// ─── Book ───
|
||
|
|
|
||
|
|
export function useBook() {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: memoirKeys.book(),
|
||
|
|
queryFn: () => memoirApi.fetchCurrentBook(),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useHasBook() {
|
||
|
|
const { data } = useBook();
|
||
|
|
return data !== null && data !== undefined;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useUpdateBookTitle() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({
|
||
|
|
bookId,
|
||
|
|
body,
|
||
|
|
}: {
|
||
|
|
bookId: string;
|
||
|
|
body: UpdateBookRequest;
|
||
|
|
}) => memoirApi.updateBookTitle(bookId, body),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: memoirKeys.book() });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// ─── Chapters ───
|
||
|
|
|
||
|
|
export function useChapters() {
|
||
|
|
const query = useQuery({
|
||
|
|
queryKey: memoirKeys.chapters(),
|
||
|
|
queryFn: () => memoirApi.fetchChapters(),
|
||
|
|
});
|
||
|
|
|
||
|
|
return {
|
||
|
|
...query,
|
||
|
|
viewModels: query.data ? toChapterViewModels(query.data) : [],
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useChapterDetail(chapterId: string) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: memoirKeys.chapterDetail(chapterId),
|
||
|
|
queryFn: () => memoirApi.fetchChapterDetail(chapterId),
|
||
|
|
enabled: !!chapterId,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useDeleteChapter() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (chapterId: string) => memoirApi.deleteChapter(chapterId),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: memoirKeys.chapters() });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// ─── Memoir state ───
|
||
|
|
|
||
|
|
export function useMemoirState() {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: memoirKeys.state(),
|
||
|
|
queryFn: () => memoirApi.fetchMemoirState(),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useNextQuestion() {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: memoirKeys.nextQuestion(),
|
||
|
|
queryFn: () => memoirApi.fetchNextQuestion(),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useMarkMemoirRead() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: () => memoirApi.markMemoirRead(),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: memoirKeys.all });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// ─── PDF export ───
|
||
|
|
|
||
|
|
export function useExportPdf() {
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (body: ExportPdfRequest) => memoirApi.exportPdf(body),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// ─── Tasks ───
|
||
|
|
|
||
|
|
export function useTasksStatus(enabled = true) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: memoirKeys.tasks(),
|
||
|
|
queryFn: () => memoirApi.fetchTasksStatus(),
|
||
|
|
enabled,
|
||
|
|
refetchInterval: (query) => {
|
||
|
|
const data = query.state.data;
|
||
|
|
if (data && !data.all_completed) return 5_000;
|
||
|
|
return false;
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useClearTasks() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: () => memoirApi.clearTasks(),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: memoirKeys.tasks() });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|