import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { ideasApi, type QueryIdeasParams } from '../services/ideas'; import type { CreateIdeaDto, UpdateIdeaDto } from '../types/idea'; import { useIdeasStore } from '../store/ideas'; const QUERY_KEY = 'ideas'; export function useIdeasQuery() { const { filters, sorting, pagination } = useIdeasStore(); const params: QueryIdeasParams = { ...filters, ...sorting, ...pagination, }; return useQuery({ queryKey: [QUERY_KEY, params], queryFn: () => ideasApi.getAll(params), }); } export function useIdeaQuery(id: string) { return useQuery({ queryKey: [QUERY_KEY, id], queryFn: () => ideasApi.getOne(id), enabled: !!id, }); } export function useModulesQuery() { return useQuery({ queryKey: [QUERY_KEY, 'modules'], queryFn: () => ideasApi.getModules(), staleTime: 60000, // Cache for 1 minute }); } export function useCreateIdea() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (dto: CreateIdeaDto) => ideasApi.create(dto), onSuccess: () => { void queryClient.invalidateQueries({ queryKey: [QUERY_KEY] }); }, }); } export function useUpdateIdea() { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ id, dto }: { id: string; dto: UpdateIdeaDto }) => ideasApi.update(id, dto), onSuccess: () => { void queryClient.invalidateQueries({ queryKey: [QUERY_KEY] }); }, }); } export function useDeleteIdea() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (id: string) => ideasApi.delete(id), onSuccess: () => { void queryClient.invalidateQueries({ queryKey: [QUERY_KEY] }); }, }); } export function useReorderIdeas() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (items: { id: string; order: number }[]) => ideasApi.reorder(items), onMutate: async (items) => { // Получаем актуальное состояние store const { filters, sorting, pagination } = useIdeasStore.getState(); // Отменяем исходящие запросы чтобы не перезаписать оптимистичное обновление await queryClient.cancelQueries({ queryKey: [QUERY_KEY] }); // Сохраняем предыдущее состояние для отката const queryKey = [QUERY_KEY, { ...filters, ...sorting, ...pagination }]; const previousData = queryClient.getQueryData(queryKey); // Оптимистично обновляем кэш queryClient.setQueryData( queryKey, ( old: | { data: { id: string; order: number }[]; meta: unknown } | undefined, ) => { if (!old) return old; // Создаём новый порядок на основе items const orderMap = new Map(items.map((item) => [item.id, item.order])); const newData = [...old.data].sort((a, b) => { const orderA = orderMap.get(a.id) ?? a.order; const orderB = orderMap.get(b.id) ?? b.order; return orderA - orderB; }); return { ...old, data: newData }; }, ); return { previousData, queryKey }; }, onError: (_err, _items, context) => { // Откатываем к предыдущему состоянию при ошибке if (context?.previousData) { queryClient.setQueryData(context.queryKey, context.previousData); } }, onSettled: () => { // Инвалидируем для синхронизации с сервером void queryClient.invalidateQueries({ queryKey: [QUERY_KEY] }); }, }); }