46 lines
1.5 KiB
TypeScript
46 lines
1.5 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { PortalApiError, portalRequest } from '@/lib/portal-api';
|
|
|
|
export function usePortalQuery<T>(url: string, delay = 0) {
|
|
const [attempt, setAttempt] = useState(0);
|
|
const key = `${url}#${attempt}`;
|
|
const [result, setResult] = useState<{
|
|
key: string;
|
|
data?: T;
|
|
error?: string;
|
|
}>({ key: '' });
|
|
|
|
useEffect(() => {
|
|
const controller = new AbortController();
|
|
const timer = setTimeout(() => {
|
|
void portalRequest<T>(url, { signal: controller.signal })
|
|
.then((data) => {
|
|
if (!controller.signal.aborted) setResult({ key, data });
|
|
})
|
|
.catch((error: unknown) => {
|
|
if (!controller.signal.aborted) {
|
|
setResult({
|
|
key,
|
|
error:
|
|
error instanceof PortalApiError
|
|
? error.message
|
|
: 'Não foi possível carregar os dados. Verifique a ligação e tente novamente.',
|
|
});
|
|
}
|
|
});
|
|
}, delay);
|
|
return () => {
|
|
clearTimeout(timer);
|
|
controller.abort();
|
|
};
|
|
}, [url, key, delay]);
|
|
|
|
const current = result.key === key ? result : undefined;
|
|
return {
|
|
data: current?.data,
|
|
error: current?.error,
|
|
loading: !current,
|
|
retry: () => setAttempt((value) => value + 1),
|
|
};
|
|
}
|