fix: handle missing isochron better
This commit is contained in:
parent
43a1c71dd1
commit
09d23e6666
1 changed files with 25 additions and 4 deletions
|
|
@ -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<LocationScoreData | null>(null);
|
||||
const [pinScoreError, setPinScoreError] = useState(false);
|
||||
const [pinAddress, setPinAddress] = useState<string | undefined>(undefined);
|
||||
const [pinEstateValue, setPinEstateValue] = useState<number | null>(null);
|
||||
const [pinEstatePercentile, setPinEstatePercentile] = useState<number | null>(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 && (
|
||||
<div className="absolute bottom-8 right-4 z-20 bg-white rounded-xl shadow-lg border border-gray-100 w-72 p-4">
|
||||
<button
|
||||
onClick={handlePinClose}
|
||||
className="absolute top-3 right-3 text-gray-300 hover:text-gray-500 text-xl leading-none"
|
||||
aria-label="Close"
|
||||
>×</button>
|
||||
<p className="text-sm text-gray-500 text-center py-4">
|
||||
No score data for this mode yet.<br />
|
||||
<span className="text-xs text-gray-400">Re-run ingest to compute new modes.</span>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{pinLocation && !pinData && !pinScoreError && (
|
||||
<div className="absolute bottom-8 right-4 z-20 bg-white rounded-xl shadow-lg border border-gray-100 w-72 p-4">
|
||||
<button
|
||||
onClick={handlePinClose}
|
||||
|
|
|
|||
Loading…
Reference in a new issue