This commit is contained in:
Andras Schmelczer 2026-05-13 08:00:12 +01:00
parent 63713c3a2b
commit bd6b511f16
17 changed files with 544 additions and 377 deletions

View file

@ -426,7 +426,7 @@ export function useHexagonSelection({
selection.type === 'hexagon' &&
!selection.lockedResolution &&
areaStats?.central_postcode != null) ||
(!usePostcodeView && selection.type === 'postcode') ||
(!usePostcodeView && selection.type === 'postcode' && !selection.lockedResolution) ||
(!usePostcodeView &&
selection.type === 'hexagon' &&
!selection.lockedResolution &&
@ -628,103 +628,38 @@ export function useHexagonSelection({
(
postcode: string,
geometry: PostcodeGeometry,
lat?: number,
lng?: number,
_lat?: number,
_lng?: number,
openProperties = false,
focusAddress?: string
) => {
const requestId = invalidateAreaRequests();
invalidatePropertyRequests();
const selection = {
id: postcode,
type: 'postcode' as const,
resolution,
lockedResolution: true,
};
trackEvent(openProperties ? 'Address Search' : 'Postcode Search');
setSelectedHexagon(selection);
setSelectedPostcodeGeometry(geometry);
setProperties([]);
setPropertiesTotal(0);
setPropertiesOffset(0);
setAreaStats(null);
setUnfilteredAreaCount(null);
setRightPaneTab(openProperties ? 'properties' : 'area');
setLoadingAreaStats(true);
// First try the postcode; if it only has no matches because of active filters,
// keep the searched postcode selected instead of widening to nearby hexagons.
fetchPostcodeStats(postcode, undefined, areaStatsUseFilters)
.then(async (stats) => {
.then((stats) => {
if (!isCurrentAreaRequest(requestId)) return;
if (stats.count > 0) {
const selection = { id: postcode, type: 'postcode' as const, resolution };
setSelectedHexagon(selection);
setSelectedPostcodeGeometry(geometry);
setAreaStats(stats);
refreshUnfilteredAreaCount(selection, stats.count, areaStatsUseFilters);
if (openProperties) {
fetchPostcodeProperties(postcode, 0, focusAddress);
}
return;
setAreaStats(stats);
refreshUnfilteredAreaCount(selection, stats.count, areaStatsUseFilters);
if (openProperties && stats.count > 0) {
fetchPostcodeProperties(postcode, 0, focusAddress);
}
if (areaStatsUseFilters && hasStatsFilters) {
const unfilteredStats = await fetchPostcodeStats(postcode, undefined, false);
if (!isCurrentAreaRequest(requestId)) return;
if (unfilteredStats.count > 0) {
const selection = { id: postcode, type: 'postcode' as const, resolution };
setSelectedHexagon(selection);
setSelectedPostcodeGeometry(geometry);
setAreaStats(stats);
setUnfilteredAreaCount(unfilteredStats.count);
setRightPaneTab(openProperties ? 'properties' : 'area');
return;
}
}
// No properties in this postcode — fall back to hexagons
if (lat == null || lng == null) {
// No coordinates available, show empty postcode anyway
const selection = { id: postcode, type: 'postcode' as const, resolution };
setSelectedHexagon(selection);
setSelectedPostcodeGeometry(geometry);
setAreaStats(stats);
refreshUnfilteredAreaCount(selection, stats.count, areaStatsUseFilters);
setRightPaneTab('area');
return;
}
// Try progressively coarser H3 resolutions until we find >1 property
const resolutions = [9, 8, 7, 6, 5];
for (const res of resolutions) {
const h3 = latLngToCell(lat, lng, res);
const hexStats = await fetchHexagonStats(
h3,
res,
undefined,
undefined,
areaStatsUseFilters
);
if (!isCurrentAreaRequest(requestId)) return;
if (hexStats.count > 1) {
const selection = { id: h3, type: 'hexagon' as const, resolution: res };
setSelectedHexagon(selection);
setSelectedPostcodeGeometry(null);
setAreaStats(hexStats);
refreshUnfilteredAreaCount(selection, hexStats.count, areaStatsUseFilters);
setRightPaneTab('area');
return;
}
}
// Even the coarsest hexagon has ≤1 property — show whatever the finest has
const h3 = latLngToCell(lat, lng, 9);
const fallbackStats = await fetchHexagonStats(
h3,
9,
undefined,
undefined,
areaStatsUseFilters
);
if (!isCurrentAreaRequest(requestId)) return;
const selection = { id: h3, type: 'hexagon' as const, resolution: 9 };
setSelectedHexagon(selection);
setSelectedPostcodeGeometry(null);
setAreaStats(fallbackStats);
refreshUnfilteredAreaCount(selection, fallbackStats.count, areaStatsUseFilters);
setRightPaneTab('area');
})
.catch((error) => logNonAbortError('Failed to fetch postcode stats', error))
.finally(() => {
@ -734,9 +669,7 @@ export function useHexagonSelection({
[
resolution,
areaStatsUseFilters,
hasStatsFilters,
fetchPostcodeStats,
fetchHexagonStats,
fetchPostcodeProperties,
invalidateAreaRequests,
invalidatePropertyRequests,