Skip to content

fix: unify station clicks, improve detour accuracy and UX#22

Merged
GeiserX merged 2 commits intomainfrom
fix/station-click-and-detour-improvements
Apr 6, 2026
Merged

fix: unify station clicks, improve detour accuracy and UX#22
GeiserX merged 2 commits intomainfrom
fix/station-click-and-detour-improvements

Conversation

@GeiserX
Copy link
Copy Markdown
Owner

@GeiserX GeiserX commented Apr 6, 2026

Summary

  • Map station clicks now trigger station-leg preview — previously only sidebar list clicks did this, map clicks only highlighted. Now both use the same useEffect path that watches selectedStationId changes.
  • Detour baseline accuracy — flags results where detourDuration - baselineDuration < -60s as failed (-1) instead of silently clamping to 0. Also includes the intermediate waypoint fix (already on main) that pins the baseline to the actual highway.
  • Station-leg errors visible — failed station-leg previews now show a transient amber toast (3s auto-dismiss) instead of being silently hidden when base routes exist.
  • Consistent route metrics — the alternatives block now uses displayRoutes[0] for the selected route during station-leg preview, matching the header metrics.
  • Detour streaming decoupled from currency — effect depends on a stable stationKey (sorted station IDs) instead of the full primaryStations collection, so currency/rate changes no longer blow away in-progress detour calculations.

Test plan

  • Click a station on the map → station-leg preview route appears + duration updates
  • Click a station in the sidebar list → same behavior as before
  • Deselect station → preview clears, base route restores
  • Trigger a station-leg route failure (e.g. station in unreachable area) → amber toast appears for 3s
  • During station-leg preview, verify alternatives block shows preview distance/duration for the selected route
  • Switch currency while detours are loading → detours continue without restarting
  • Route with distant stations (25km corridor) → detour values should not show 0 for clearly non-zero detours

Summary by CodeRabbit

  • Bug Fixes

    • Improved detour time handling for negative and outlier deltas, avoiding misleading zeroed values
    • Prevented unnecessary route recalculations when station data reference changes without ID changes
    • Clearing station-preview state on request aborts/errors
  • Improvements

    • Auto-clears transient route errors after a short timeout
    • More accurate route metrics display when selecting alternative routes
  • New Features

    • Auto-triggered station-leg preview logic with a brief amber toast for station-related errors

- Map station clicks now trigger station-leg preview (same as sidebar)
- Detour baseline flags large negative diffs as failed (-1) instead of
  silently clamping to 0, exposing bad baseline matches
- Station-leg route errors show as transient amber toast (3s auto-dismiss)
  instead of being invisible when base routes exist
- Route alternatives block uses preview metrics for the selected route
  during station-leg preview, keeping numbers consistent
- Detour streaming depends on station IDs instead of the full converted
  collection, preventing currency changes from restarting calculations
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8c502a26-e8a9-437a-82e5-8ddb4454366f

📥 Commits

Reviewing files that changed from the base of the PR and between ee803de and 35c3323.

📒 Files selected for processing (1)
  • src/components/home-client.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/home-client.tsx

📝 Walkthrough

Walkthrough

Changed detour delta handling to compute a signed raw delta and reject large negative deltas; stabilized primary-stations referencing to avoid redundant detour recomputation; added auto-triggered station-leg logic with transient error toast and adjusted route-row metric selection.

Changes

Cohort / File(s) Summary
Detour Calculation
src/app/api/route-detour/route.ts
Replace clamped delta (Math.max(0, detour−baseline)) with raw signed delta; return { id, detourMin: -1 } when delta < −60s; otherwise compute detour minutes using clamped non-negative seconds before rounding.
Client: Station-leg & Detour Trigger
src/components/home-client.tsx
Use memoized stationKey and primaryStationsRef to avoid effect reruns on reference-only changes; switch detour eligibility to read from primaryStationsRef.current; clear selectedStationId on abort/error/empty-route and when cancelling preview.
Search Panel: Auto-trigger & Error UI
src/components/search/search-panel.tsx
Add transient stationLegError with auto-clear; introduce ref-backed auto-trigger (handleStationLegRef, primaryStationsRef, prevSelectedRef) to invoke station-leg when selectedStationId changes; show amber toast for station-leg errors; remove direct handleStationLeg call from station list button; adjust route-row metrics to prefer displayRoutes?.[0] when selected.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • GeiserX/Pumperly PR 21 — related detour calculation and per-station result handling changes in the route-detour endpoint.
  • GeiserX/Pumperly PR 17 — changes to baseline/delta computation for detours overlapping this endpoint’s logic.
  • GeiserX/Pumperly PR 16 — modifications to detour exit/rejoin and baseline/detour duration calculations that touch the same API logic.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main changes: unifying station click handling, improving detour accuracy calculation, and enhancing UX with error visibility and consistent metrics.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/station-click-and-detour-improvements

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/components/search/search-panel.tsx (1)

419-433: Auto-trigger logic is sound.

The prevSelectedRef comparison prevents spurious triggers when other deps change. Ref-based handler/data access avoids stale closures.

Minor: Line 430 station.properties.brand ?? station.properties.name could be undefined if both are nullish, resulting in "undefined" displayed in the waypoint label. Consider a fallback:

-      station.properties.brand ?? station.properties.name,
+      station.properties.brand ?? station.properties.name ?? station.properties.id,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/search/search-panel.tsx` around lines 419 - 433, The label
fallback can still produce "undefined" when both brand and name are nullish;
update the call in the useEffect where handleStationLegRef.current is invoked
(inside the selectedStationId/phase effect) to pass a safe fallback string
instead of station.properties.brand ?? station.properties.name — for example use
station.properties.brand ?? station.properties.name ?? `Waypoint
${station.properties.id}` or a generic 'Waypoint' so the waypoint label never
ends up as "undefined"; adjust the argument passed to
handleStationLegRef.current accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/components/search/search-panel.tsx`:
- Around line 419-433: The label fallback can still produce "undefined" when
both brand and name are nullish; update the call in the useEffect where
handleStationLegRef.current is invoked (inside the selectedStationId/phase
effect) to pass a safe fallback string instead of station.properties.brand ??
station.properties.name — for example use station.properties.brand ??
station.properties.name ?? `Waypoint ${station.properties.id}` or a generic
'Waypoint' so the waypoint label never ends up as "undefined"; adjust the
argument passed to handleStationLegRef.current accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a2ef2a12-e110-4340-9147-d872634d5d2f

📥 Commits

Reviewing files that changed from the base of the PR and between 7d893af and ee803de.

📒 Files selected for processing (3)
  • src/app/api/route-detour/route.ts
  • src/components/home-client.tsx
  • src/components/search/search-panel.tsx

When a station-leg preview fails or its waypoint is removed,
selectedStationId is now cleared. This allows re-clicking the same
station to trigger a new preview, since the useEffect depends on
the value actually changing.
@GeiserX GeiserX merged commit bc1948b into main Apr 6, 2026
8 checks passed
@GeiserX GeiserX deleted the fix/station-click-and-detour-improvements branch April 6, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant