Format and lint

This commit is contained in:
Andras Schmelczer 2026-02-08 12:37:07 +00:00
parent 42ee2d4c51
commit 04a78e7bfe
75 changed files with 1290 additions and 719 deletions

View file

@ -2,11 +2,9 @@ import { useState, useCallback } from 'react';
import type {
FeatureMeta,
FeatureFilters,
PostcodeFeature,
Property,
HexagonPropertiesResponse,
HexagonStatsResponse,
NumericFeatureStats,
} from '../types';
import { buildFilterString, apiUrl, logNonAbortError, authHeaders } from '../lib/api';
@ -19,16 +17,10 @@ interface SelectedHexagon {
interface UseHexagonSelectionOptions {
filters: FeatureFilters;
features: FeatureMeta[];
postcodeData: PostcodeFeature[];
resolution: number;
}
export function useHexagonSelection({
filters,
features,
postcodeData,
resolution,
}: UseHexagonSelectionOptions) {
export function useHexagonSelection({ filters, features, resolution }: UseHexagonSelectionOptions) {
const [selectedHexagon, setSelectedHexagon] = useState<SelectedHexagon | null>(null);
const [properties, setProperties] = useState<Property[]>([]);
const [propertiesTotal, setPropertiesTotal] = useState(0);
@ -56,31 +48,15 @@ export function useHexagonSelection({
[filters, features]
);
const buildPostcodeStats = useCallback(
(postcode: string): HexagonStatsResponse | null => {
const feat = postcodeData.find((f) => f.properties.postcode === postcode);
if (!feat) return null;
const props = feat.properties;
const numeric_features: NumericFeatureStats[] = [];
for (const f of features) {
if (f.type !== 'numeric') continue;
const minVal = props[`min_${f.name}`];
const maxVal = props[`max_${f.name}`];
if (typeof minVal !== 'number' || typeof maxVal !== 'number') continue;
const avgVal = props[`avg_${f.name}`];
numeric_features.push({
name: f.name,
count: props.count,
min: minVal,
max: maxVal,
mean: typeof avgVal === 'number' ? avgVal : (minVal + maxVal) / 2,
});
}
return { count: props.count, numeric_features, enum_features: [] };
const fetchPostcodeStats = useCallback(
async (postcode: string, signal?: AbortSignal) => {
const params = new URLSearchParams({ postcode });
const filterStr = buildFilterString(filters, features);
if (filterStr) params.append('filters', filterStr);
const response = await fetch(apiUrl('postcode-stats', params), authHeaders({ signal }));
return (await response.json()) as HexagonStatsResponse;
},
[postcodeData, features]
[filters, features]
);
const fetchHexagonProperties = useCallback(
@ -131,8 +107,11 @@ export function useHexagonSelection({
setRightPaneTab('area');
if (isPostcode) {
setAreaStats(buildPostcodeStats(id));
setLoadingAreaStats(false);
setLoadingAreaStats(true);
fetchPostcodeStats(id)
.then((stats) => setAreaStats(stats))
.catch((error) => logNonAbortError('Failed to fetch postcode stats', error))
.finally(() => setLoadingAreaStats(false));
} else {
setLoadingAreaStats(true);
fetchHexagonStats(id, resolution)
@ -142,7 +121,7 @@ export function useHexagonSelection({
}
}
},
[selectedHexagon, resolution, fetchHexagonStats, buildPostcodeStats]
[selectedHexagon, resolution, fetchHexagonStats, fetchPostcodeStats]
);
const handleHexagonHover = useCallback((h3: string | null) => {