Skip to content

Commit 0c246d1

Browse files
committed
fix(review): meaningful beyond-cutoff bands test, LogoChip escape/click-outside dismiss, drop orphaned useIsochrone
Final-review follow-ups. Remaining minors (degraded-mode double fetch and reduce-time flicker on band-less providers, desktop-only empty hint) recorded as acceptable follow-ups - they only affect ISOCHRONE_PROVIDER=ors.
1 parent a16eead commit 0c246d1

4 files changed

Lines changed: 32 additions & 52 deletions

File tree

apps/web/src/app/page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
* State flow:
77
* URL ──parse──► state ──serialize──► history.replaceState
88
* │
9-
* ├──► <IlsochroneMap origin={...} polygon={...} />
10-
* ├──► <TimeSelector value={minutes} />
11-
* └──► useIsochrone(...) → SWR → /api/isochrone → ORS
9+
* ├──► <IlsochroneMap origin={...} bands={...} />
10+
* ├──► <TimeSelector value={minutes} /> (pure client state)
11+
* └──► useIsochroneBands(...) → SWR → /api/isochrone?bands=1local engine
1212
*/
1313
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
1414
import dynamic from 'next/dynamic';

apps/web/src/components/brand/LogoChip.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,31 @@
11
'use client';
22

3-
import { useState } from 'react';
3+
import { useEffect, useRef, useState } from 'react';
44
import { Info } from 'lucide-react';
55

66
export function LogoChip() {
77
const [open, setOpen] = useState(false);
8+
const rootRef = useRef<HTMLDivElement>(null);
9+
10+
// Escape and click-outside dismiss the info popover.
11+
useEffect(() => {
12+
if (!open) return;
13+
const onKey = (e: KeyboardEvent) => {
14+
if (e.key === 'Escape') setOpen(false);
15+
};
16+
const onDown = (e: MouseEvent) => {
17+
if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false);
18+
};
19+
document.addEventListener('keydown', onKey);
20+
document.addEventListener('mousedown', onDown);
21+
return () => {
22+
document.removeEventListener('keydown', onKey);
23+
document.removeEventListener('mousedown', onDown);
24+
};
25+
}, [open]);
26+
827
return (
9-
<div className="relative">
28+
<div ref={rootRef} className="relative">
1029
<button
1130
type="button"
1231
onClick={() => setOpen((v) => !v)}

apps/web/src/lib/hooks/useIsochrone.ts

Lines changed: 0 additions & 45 deletions
This file was deleted.

packages/engine/src/__tests__/bands.test.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,14 @@ const CENTER: [number, number] = [34.7821, 32.0818];
1818

1919
describe('computeIsochroneBands', () => {
2020
it('one pass equals per-band computeIsochrone results', () => {
21-
const { bands, snapDistanceM } = computeIsochroneBands(GRID, CENTER, [5, 10, 15]);
22-
expect(bands.map((b) => b.minutes)).toEqual([5, 10, 15]);
21+
// Bands chosen so the grid genuinely straddles cutoffs: at 2 min (120 s)
22+
// the 144 s neighbors are beyond the band but finite in the shared
23+
// max-cutoff times array — the exact window where the one-pass
24+
// optimization could diverge from solo runs if the beyond-cutoff
25+
// interpolation were wrong. (With all-nodes-inside bands the deep-equal
26+
// would pass vacuously.)
27+
const { bands, snapDistanceM } = computeIsochroneBands(GRID, CENTER, [2, 5, 10]);
28+
expect(bands.map((b) => b.minutes)).toEqual([2, 5, 10]);
2329
expect(snapDistanceM).toBeLessThan(10);
2430
for (const band of bands) {
2531
const solo = computeIsochrone(GRID, CENTER, band.minutes);

0 commit comments

Comments
 (0)