Files
Investidor-V2/resources/js/components/use-territory-geometry.ts
T

66 lines
2.4 KiB
TypeScript

import { useEffect, useState } from 'react';
import type { InvestmentMapArea } from './interactive-investment-map';
export type TerritoryGeometryContext = {
selected_geometry_available: boolean;
context_geometry_count: number;
areas: InvestmentMapArea[];
truncated: boolean;
child_coverage?: {
location_type: string | null;
registered_count: number;
represented_count: number;
reference_limit: number;
geometry_limit: number;
} | null;
};
export function useTerritoryGeometry(
territoryId?: string,
endpoint = '/api/v1/investment/territory-geometries',
includeChildren = false,
) {
const key = JSON.stringify([territoryId, endpoint, includeChildren]);
const [result, setResult] = useState<{
key: string;
context: TerritoryGeometryContext | null;
error: string;
}>({ key, context: null, error: '' });
useEffect(() => {
const controller = new AbortController();
setResult({ key, context: null, error: '' });
if (!territoryId) return () => controller.abort();
void fetch(
`${endpoint}?${new URLSearchParams({ territory_id: territoryId, ...(includeChildren ? { include_children: '1' } : {}) })}`,
{
signal: controller.signal,
headers: { Accept: 'application/json' },
},
)
.then(async (response) => {
if (!response.ok)
throw new Error(
'Não foi possível consultar os limites administrativos.',
);
return response.json() as Promise<TerritoryGeometryContext>;
})
.then((context) => {
if (!controller.signal.aborted)
setResult({ key, context, error: '' });
})
.catch((error: unknown) => {
if (!controller.signal.aborted)
setResult({
key,
context: null,
error:
error instanceof Error
? error.message
: 'Erro de ligação.',
});
});
return () => controller.abort();
}, [key, territoryId, endpoint, includeChildren]);
return result.key === key ? result : { key, context: null, error: '' };
}