diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx index 8b419da..c2dafcf 100644 --- a/apps/web/app/page.tsx +++ b/apps/web/app/page.tsx @@ -40,6 +40,7 @@ export default function HomePage() { // Pin / location rating const [pinLocation, setPinLocation] = useState<{ lat: number; lng: number } | null>(null); const [pinData, setPinData] = useState(null); + const [pinScoreError, setPinScoreError] = useState(false); const [pinAddress, setPinAddress] = useState(undefined); const [pinEstateValue, setPinEstateValue] = useState(null); const [pinEstatePercentile, setPinEstatePercentile] = useState(null); @@ -100,11 +101,13 @@ export default function HomePage() { useEffect(() => { if (!pinLocation || !selectedCity) { setPinData(null); + setPinScoreError(false); setPinAddress(undefined); return; } let cancelled = false; + setPinScoreError(false); const params = new URLSearchParams({ lat: String(pinLocation.lat), @@ -128,14 +131,15 @@ export default function HomePage() { .then(([scoreData, address]) => { if (cancelled) return; if (scoreData?.error) { - // No grid data for this location — clear the pin so the skeleton doesn't persist. - setPinLocation(null); + // No grid data for this mode — keep the pin (isochrone may still show) but + // display an error state instead of an infinite loading skeleton. + setPinScoreError(true); return; } setPinData(scoreData as LocationScoreData); setPinAddress(address); }) - .catch(() => { if (!cancelled) setPinLocation(null); }); + .catch(() => { if (!cancelled) setPinScoreError(true); }); return () => { cancelled = true; }; }, [pinLocation, selectedCity, mode, threshold, profile]); @@ -252,6 +256,7 @@ export default function HomePage() { // Clear pin when profile changes so scores are re-fetched with new profile setPinLocation(null); setPinData(null); + setPinScoreError(false); setPinAddress(undefined); setPinEstateValue(null); setPinEstatePercentile(null); @@ -262,6 +267,7 @@ export default function HomePage() { function handleLocationClick(lat: number, lng: number, estateValue: number | null) { setPinLocation({ lat, lng }); setPinData(null); + setPinScoreError(false); setPinAddress(undefined); setPinEstateValue(estateValue); setPinEstatePercentile(null); @@ -272,6 +278,7 @@ export default function HomePage() { function handlePinClose() { setPinLocation(null); setPinData(null); + setPinScoreError(false); setPinAddress(undefined); setPinEstateValue(null); setPinEstatePercentile(null); @@ -351,7 +358,21 @@ export default function HomePage() { hasPinData={!!pinData} /> - {pinLocation && !pinData && ( + {pinLocation && !pinData && pinScoreError && ( +
+ +

+ No score data for this mode yet.
+ Re-run ingest to compute new modes. +

+
+ )} + + {pinLocation && !pinData && !pinScoreError && (