generated from Gallardo7761/miarma-template-full
141 lines
3.7 KiB
JavaScript
141 lines
3.7 KiB
JavaScript
import { useState, useEffect, useCallback, useRef } from "react";
|
|
import axios from "axios";
|
|
|
|
export const useData = (config, onError) => {
|
|
const [data, setData] = useState(null);
|
|
const [dataLoading, setLoading] = useState(true);
|
|
const [dataError, setError] = useState(null);
|
|
const configRef = useRef();
|
|
|
|
useEffect(() => {
|
|
if (config?.baseUrl) {
|
|
configRef.current = config;
|
|
}
|
|
}, [config]);
|
|
|
|
const getAuthHeaders = (isFormData = false) => {
|
|
const token = localStorage.getItem("token");
|
|
|
|
const headers = {};
|
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
|
|
if (!isFormData) {
|
|
headers["Content-Type"] = "application/json";
|
|
}
|
|
|
|
return headers;
|
|
};
|
|
|
|
const handleAxiosError = (err) => {
|
|
if (err.response && err.response.data) {
|
|
const data = err.response.data;
|
|
|
|
if (data.status === 422 && data.errors) {
|
|
return {
|
|
status: 422,
|
|
errors: data.errors,
|
|
path: data.path ?? null,
|
|
timestamp: data.timestamp ?? null,
|
|
};
|
|
}
|
|
|
|
return {
|
|
status: data.status ?? err.response.status,
|
|
error: data.error ?? null,
|
|
message: data.message ?? err.response.statusText ?? "Error desconocido",
|
|
path: data.path ?? null,
|
|
timestamp: data.timestamp ?? null,
|
|
};
|
|
}
|
|
|
|
if (err.request) {
|
|
return {
|
|
status: null,
|
|
error: "Network Error",
|
|
message: "No se pudo conectar al servidor",
|
|
path: null,
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
}
|
|
|
|
return {
|
|
status: null,
|
|
error: "Client Error",
|
|
message: err.message || "Error desconocido",
|
|
path: null,
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
};
|
|
|
|
const fetchData = useCallback(async () => {
|
|
const current = configRef.current;
|
|
if (!current?.baseUrl) return;
|
|
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await axios.get(current.baseUrl, {
|
|
headers: getAuthHeaders(),
|
|
params: current.params,
|
|
});
|
|
setData(response.data);
|
|
} catch (err) {
|
|
const error = handleAxiosError(err);
|
|
setError(error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (config?.baseUrl) fetchData();
|
|
}, [config, fetchData]);
|
|
|
|
const requestWrapper = async (method, endpoint, payload = null, refresh = false) => {
|
|
try {
|
|
const isFormData = payload instanceof FormData;
|
|
const headers = getAuthHeaders(isFormData);
|
|
const cfg = { headers };
|
|
let response;
|
|
|
|
if (method === "get") {
|
|
if (payload) cfg.params = payload;
|
|
response = await axios.get(endpoint, cfg);
|
|
} else if (method === "delete") {
|
|
if (payload) cfg.data = payload;
|
|
response = await axios.delete(endpoint, cfg);
|
|
} else {
|
|
response = await axios[method](endpoint, payload, cfg);
|
|
}
|
|
|
|
if (refresh) await fetchData();
|
|
return response.data;
|
|
|
|
} catch (err) {
|
|
const error = handleAxiosError(err);
|
|
|
|
if (error.status !== 422 && onError) {
|
|
onError(error);
|
|
}
|
|
|
|
setError(error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
const clearError = () => setError(null);
|
|
|
|
return {
|
|
data,
|
|
dataLoading,
|
|
dataError,
|
|
clearError,
|
|
getData: (url, params, refresh = true) => requestWrapper("get", url, params, refresh),
|
|
postData: (url, body, refresh = true) => requestWrapper("post", url, body, refresh),
|
|
putData: (url, body, refresh = true) => requestWrapper("put", url, body, refresh),
|
|
deleteData: (url, refresh = true) => requestWrapper("delete", url, null, refresh),
|
|
deleteDataWithBody: (url, body, refresh = true) => requestWrapper("delete", url, body, refresh)
|
|
};
|
|
};
|