import { useState, useCallback } from 'react'; import { toast } from 'react-hot-toast'; import api from '@/lib/api'; /** * Типы состояний запроса */ export type ApiStatus = 'idle' | 'loading' | 'success' | 'error'; /** * Интерфейс для опций хука */ interface UseAdminApiOptions { onSuccess?: (data: any) => void; onError?: (error: any) => void; showSuccessToast?: boolean; showErrorToast?: boolean; successMessage?: string; errorMessage?: string; } /** * Хук для работы с API в админке * @param options Опции хука * @returns Объект с функциями и состоянием */ export function useAdminApi(options: UseAdminApiOptions = {}) { const [status, setStatus] = useState('idle'); const [data, setData] = useState(null); const [error, setError] = useState(null); const { onSuccess, onError, showSuccessToast = false, showErrorToast = true, successMessage = 'Операция выполнена успешно', errorMessage = 'Произошла ошибка при выполнении операции' } = options; /** * Обработка ошибки API */ const handleError = useCallback((err: any, customMessage?: string) => { console.error('API Error:', err); // Формируем сообщение об ошибке let message = customMessage || errorMessage; if (err?.response?.data?.detail) { message = err.response.data.detail; } else if (err?.message) { message = err.message; } // Устанавливаем состояние ошибки setError(message); setStatus('error'); // Показываем уведомление об ошибке if (showErrorToast) { toast.error(message); } // Вызываем пользовательский обработчик ошибки if (onError) { onError(err); } }, [errorMessage, showErrorToast, onError]); /** * Выполнение GET запроса */ const get = useCallback(async (url: string, params = {}) => { try { setStatus('loading'); setError(null); const response = await api.get(url, { params }); setData(response); setStatus('success'); if (showSuccessToast) { toast.success(successMessage); } if (onSuccess) { onSuccess(response); } return response; } catch (err) { handleError(err); return null; } }, [handleError, onSuccess, showSuccessToast, successMessage]); /** * Выполнение POST запроса */ const post = useCallback(async (url: string, data = {}, config = {}) => { try { setStatus('loading'); setError(null); const response = await api.post(url, data, config); setData(response); setStatus('success'); if (showSuccessToast) { toast.success(successMessage); } if (onSuccess) { onSuccess(response); } return response; } catch (err) { handleError(err); return null; } }, [handleError, onSuccess, showSuccessToast, successMessage]); /** * Выполнение PUT запроса */ const put = useCallback(async (url: string, data = {}, config = {}) => { try { setStatus('loading'); setError(null); const response = await api.put(url, data, config); setData(response); setStatus('success'); if (showSuccessToast) { toast.success(successMessage); } if (onSuccess) { onSuccess(response); } return response; } catch (err) { handleError(err); return null; } }, [handleError, onSuccess, showSuccessToast, successMessage]); /** * Выполнение DELETE запроса */ const del = useCallback(async (url: string, config = {}) => { try { setStatus('loading'); setError(null); const response = await api.delete(url, config); setData(response); setStatus('success'); if (showSuccessToast) { toast.success(successMessage); } if (onSuccess) { onSuccess(response); } return response; } catch (err) { handleError(err); return null; } }, [handleError, onSuccess, showSuccessToast, successMessage]); /** * Сброс состояния */ const reset = useCallback(() => { setStatus('idle'); setData(null); setError(null); }, []); return { status, isLoading: status === 'loading', isSuccess: status === 'success', isError: status === 'error', data, error, get, post, put, delete: del, reset, setData, setError, setStatus }; } export default useAdminApi;