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() }); }, }); } export function useCheckCoverGeneration() { const queryClient = useQueryClient(); return useMutation({ mutationFn: () => memoirApi.checkCoverGeneration(), onSuccess: (data) => { if (data.triggered.length > 0) { 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() }); }, }); }