Optimisations

This commit is contained in:
Andras Schmelczer 2026-02-01 21:00:59 +00:00
parent 66c2a25457
commit 9179acd4cd
21 changed files with 653 additions and 139 deletions

View file

@ -1,4 +1,5 @@
import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
import { trackPageview } from './usePlausible';
import Map from './components/Map';
import Filters from './components/Filters';
import POIPane from './components/POIPane';
@ -57,6 +58,11 @@ async function fetchWithRetry<T>(
// Detect if running through VS Code web proxy and construct API base URL
function getApiBaseUrl(): string {
// In production builds, always use same-origin (Rust server serves both API and frontend)
if (process.env.NODE_ENV === 'production') {
return '';
}
const { pathname, href } = window.location;
// Check pathname for /proxy/PORT pattern (VS Code web proxy)
@ -71,7 +77,7 @@ function getApiBaseUrl(): string {
return `${hrefMatch[1]}8001`;
}
// Default: same origin (works for both local dev with webpack proxy and production)
// Default: same origin (works for local dev with webpack proxy)
return '';
}
@ -417,6 +423,7 @@ export default function App() {
const url = hash ? `${window.location.pathname}${window.location.search}#${hash}` : `${window.location.pathname}${window.location.search}`;
window.history.pushState({ page }, '', url);
setActivePage(page);
trackPageview();
}, []);
// Handle browser back/forward
@ -465,8 +472,9 @@ export default function App() {
// Derive view feature: active drag takes priority over pinned
const viewFeature = activeFeature || pinnedFeature;
const viewSource: 'drag' | 'eye' | null = activeFeature ? 'drag' : pinnedFeature ? 'eye' : null;
// Color range: always the feature's full slider range from metadata
// For enum features, use ordinal index range [0, values.length - 1]
// Color range: use the filter slider range when a numeric filter is active,
// otherwise fall back to the feature's full range from metadata.
// For enum features, use ordinal index range [0, values.length - 1].
const colorRange = useMemo((): [number, number] | null => {
if (!viewFeature) return null;
const meta = features.find((f) => f.name === viewFeature);
@ -474,9 +482,13 @@ export default function App() {
if (meta.type === 'enum' && meta.values && meta.values.length > 0) {
return [0, meta.values.length - 1];
}
// Use live drag values or committed filter range if available
if (activeFeature === viewFeature && dragValue) return dragValue;
const filterVal = filters[viewFeature];
if (filterVal && typeof filterVal[0] === 'number') return filterVal as [number, number];
if (meta.min != null && meta.max != null) return [meta.min, meta.max];
return null;
}, [viewFeature, features]);
}, [viewFeature, features, activeFeature, dragValue, filters]);
// Filter range: current drag or committed filter values, used for gray-out
const filterRange = useMemo((): [number, number] | null => {
@ -1087,6 +1099,22 @@ export default function App() {
onHoverModeChange={setHoverMode}
onViewProperties={handleViewPropertiesFromArea}
onClose={handleCloseProperties}
hexagonLocation={
(() => {
const hexId = hoverMode && hoveredHexagon && hoveredHexagon !== selectedHexagon?.h3
? hoveredHexagon
: selectedHexagon?.h3;
const hex = hexId ? data.find((d) => d.h3 === hexId) : null;
if (!hex || typeof hex.lat !== 'number' || typeof hex.lon !== 'number') return null;
return {
lat: hex.lat as number,
lon: hex.lon as number,
postcode: (hex.postcode as string | undefined) ?? null,
resolution,
};
})()
}
filters={filters}
/>
) : rightPaneTab === 'properties' ? (
<PropertiesPane