import { useQuery, useMutation, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query'; import { toast } from 'react-hot-toast'; import api from '@/lib/api'; import { cacheKeys } from '@/lib/api-cache'; export function useAdminQuery( key: string | string[], url: string, params: Record = {}, options: Omit, 'queryKey' | 'queryFn'> = {} ) { const queryKey = Array.isArray(key) ? key : [key]; return useQuery({ queryKey, queryFn: async () => { try { return await api.get(url, { params }); } catch (error) { console.error(`Error fetching data from ${url}:`, error); throw error; } }, ...options }); } export function useAdminMutation( method: 'post' | 'put' | 'delete', url: string, options: { onSuccessMessage?: string; onErrorMessage?: string; invalidateQueries?: (string | string[])[]; mutationOptions?: Omit, 'mutationFn'>; } = {} ) { const queryClient = useQueryClient(); const { onSuccessMessage = 'Операция выполнена успешно', onErrorMessage = 'Произошла ошибка при выполнении операции', invalidateQueries = [], mutationOptions = {} } = options; return useMutation({ mutationFn: async (variables) => { try { if (method === 'delete') { return await api.delete(url); } else { return await api[method](url, variables); } } catch (error) { console.error(`Error executing ${method.toUpperCase()} ${url}:`, error); throw error; } }, onSuccess: (data, variables, context) => { if (onSuccessMessage) toast.success(onSuccessMessage); if (invalidateQueries.length > 0) { invalidateQueries.forEach(key => { if (Array.isArray(key)) { queryClient.invalidateQueries({ queryKey: key }); } else { queryClient.invalidateQueries({ queryKey: [key] }); } }); } if (mutationOptions.onSuccess) { mutationOptions.onSuccess(data, variables, context); } }, onError: (error, variables, context) => { if (onErrorMessage) toast.error(onErrorMessage); if (mutationOptions.onError) { mutationOptions.onError(error, variables, context); } }, ...mutationOptions }); } export function useProducts(params: Record = {}, options = {}) { return useAdminQuery( [cacheKeys.products, JSON.stringify(params)], '/catalog/products', params, options ); } export function useProduct(id: number | string, options = {}) { return useAdminQuery( cacheKeys.product(id), `/catalog/products/${id}`, {}, options ); } export function useCategories(params: Record = {}, options = {}) { return useAdminQuery( [cacheKeys.categories, JSON.stringify(params)], '/catalog/categories', params, options ); } export function useCollections(params: Record = {}, options = {}) { return useAdminQuery( [cacheKeys.collections, JSON.stringify(params)], '/catalog/collections', params, options ); } export function useSizes(params: Record = {}, options = {}) { return useAdminQuery( [cacheKeys.sizes, JSON.stringify(params)], '/catalog/sizes', params, options ); } export function useOrders(params: Record = {}, options = {}) { return useAdminQuery( [cacheKeys.orders, JSON.stringify(params)], '/admin/orders', params, options ); } export function useOrder(id: number | string, options = {}) { return useAdminQuery( cacheKeys.order(id), `/admin/orders/${id}`, {}, options ); } export function useDashboardStats(options = {}) { return useAdminQuery( cacheKeys.dashboardStats, '/admin/dashboard/stats', {}, options ); } export function useRecentOrders(limit = 5, options = {}) { return useAdminQuery( cacheKeys.recentOrders, '/admin/orders/recent', { limit }, options ); } export function usePopularProducts(limit = 5, options = {}) { return useAdminQuery( cacheKeys.popularProducts, '/admin/products/popular', { limit }, options ); } export default { useAdminQuery, useAdminMutation, useProducts, useProduct, useCategories, useCollections, useSizes, useOrders, useOrder, useDashboardStats, useRecentOrders, usePopularProducts };