dressed_for_succes_store/frontend/hooks/useAdminApi.ts

211 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<ApiStatus>('idle');
const [data, setData] = useState<any>(null);
const [error, setError] = useState<any>(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 <T>(url: string, params = {}) => {
try {
setStatus('loading');
setError(null);
const response = await api.get<T>(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 <T>(url: string, data = {}, config = {}) => {
try {
setStatus('loading');
setError(null);
const response = await api.post<T>(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 <T>(url: string, data = {}, config = {}) => {
try {
setStatus('loading');
setError(null);
const response = await api.put<T>(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 <T>(url: string, config = {}) => {
try {
setStatus('loading');
setError(null);
const response = await api.delete<T>(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;