Skip to content

HI-FI: Update Expanded Route Timeline Badges#160

Open
KesarSidhu wants to merge 10 commits into
benevolentbandwidth:mainfrom
KesarSidhu:step3-edit-look-3-main-v1
Open

HI-FI: Update Expanded Route Timeline Badges#160
KesarSidhu wants to merge 10 commits into
benevolentbandwidth:mainfrom
KesarSidhu:step3-edit-look-3-main-v1

Conversation

@KesarSidhu
Copy link
Copy Markdown
Contributor

@KesarSidhu KesarSidhu commented May 11, 2026

Summary

Expanded route cards on the results sidebar use a hi-fi timeline layout: cyan sequence badges, dotted connectors between stops, and stop cards that show the sequence only once.

Motivation

The previous expanded stop list used a flat stack with a duplicate sequence badge inside each card. The hi-fi design calls for a vertical timeline so drivers can scan stop order at a glance.

Changes

  • app/ui/src/app/results/components/Sidebar.tsx
    • Reworked expanded stops into a timeline row (badge column + card column).
    • Added cyan rounded-square sequence badges and dotted vertical connectors (isLastStop omits the trailing line).
    • Updated expanded-panel padding and spacing; connector uses w-0 + border-l-2.
  • app/ui/src/app/results/components/EditableStopItem.tsx
    • Removed the inner zinc sequence badge so the number appears only in the sidebar timeline marker.

Validation

Frontend

  • npm --prefix app/ui run lint
  • npm --prefix app/ui run typecheck
  • npm --prefix app/ui run format:check
  • npm --prefix app/ui run test
  • npm --prefix app/ui run build
  • npm --prefix app/mobile run lint
  • npm --prefix app/mobile run typecheck

Backend

  • cmake --preset dev

  • .github/scripts/check-backend-static.sh build/dev

  • cmake --build --preset dev --parallel

  • ctest --preset dev --output-on-failure --no-tests=error -LE 'e2e|docker'

  • docker compose -f deploy/compose/docker-compose.arm64.yml --env-file deploy/env/http-server.arm64.env config

  • Manually verified expanded routes on /results: one sequence badge per stop, connectors between stops, no duplicate numbers in cards.

Risk

Low — UI-only; no API, routing, or sessionStorage behavior changes.

Rollout and Recovery

Ship with the results page. Revert this PR if timeline spacing or badge styling needs adjustment.

@markboenigk
Copy link
Copy Markdown
Collaborator

Thanks for the timeline redesign — the cyan badges + dotted connector pattern looks clean and the isLastStop guard to drop the trailing line is a nice touch.

One bug to fix before merge: EditableStopItem already renders its own sequence badge (h-6 w-6 bg-zinc-600 at line 21), so every stop will show the sequence number twice — once in the new outer cyan marker, once inside the card. The fix is to remove the sequence badge from EditableStopItem (or add a prop to suppress it) in this same PR.

Two minor nits:

  • The connector div uses both w-px and border-l-2w-px has no effect here since the visible line is the border, not the element's width. w-0 reads clearer.
  • The template literal ${isLastStop ? "" : "pb-5"} leaves a trailing space on last stops. If the project has clsx/cn() available, that's the idiomatic way to handle conditional classes.

The rest looks good — aria-hidden on the connector, shrink-0 on the badge column, min-h-[20px] to prevent a zero-height line. Happy to approve once the duplicate sequence badge is resolved.

@KesarSidhu KesarSidhu force-pushed the step3-edit-look-3-main-v1 branch from d5f6c00 to 9a22c48 Compare May 17, 2026 22:38
@KesarSidhu KesarSidhu force-pushed the step3-edit-look-3-main-v1 branch from b23b7a0 to 45daa2a Compare May 25, 2026 01:45
Copy link
Copy Markdown
Collaborator

@kirillakovalenko kirillakovalenko left a comment

Choose a reason for hiding this comment

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

PR #160 — HI-FI: Update Expanded Route Timeline Badges
Author: KesarSidhu | +397 / -198 across 7 files | Status: OPEN

Overview
This PR redesigns the results page sidebar with a hi-fi timeline layout: cyan sequence badges with dotted connectors between stops, a new route card design with an icon, a revamped header with a shared nav sidebar, and custom SVG map pin markers per route color. It also upgrades SidebarResultsButton to have active/inactive/disabled states based on sessionStorage.

Bugs

  1. "Save" pin-move button is always rendered — page.tsx:722-729

The "Cancel" button is correctly gated behind pendingPinMove != null, but the new "Save" button sits outside that condition and is always visible. Clicking it when nothing is pending will call savePendingPinMove with null state.

  • {pendingPinMove != null && (
    Cancel
  • )}
  • Save ← always visible
  • {pendingPinMove != null && (
  • <>
  •  <button onClick={cancelPendingPinMove}>Cancel</button>
    
  •  <button onClick={savePendingPinMove}>Save</button>
    
  • </>
  • )}
  1. Advanced marker anchor offset is wrong — Map.tsx:163-164

The comment says "shift so the SVG tip sits on the stop," but translate(-50%, -50%) places the center of the 28×40 wrapper at the coordinate, not the bottom tip. For a pin shape, it should be translate(-50%, -100%) to anchor the tip at the lat/lng point.

Non-functional / Incomplete Code
3. Export button has no handler — page.tsx:730-735

Export {/* no onClick */} This is a visible dead button. Either gate it or add a TODO comment so reviewers know it's intentional.
  1. isSidebarOpen hardcoded to true — page.tsx:652

const isSidebarOpen = true; // was: useState(true)
The toggle button was removed, which is fine if the sidebar is always open. But leaving the variable (used only to set a CSS class) is dead code. Remove the isSidebarOpen variable and inline "w-[28rem]" directly, or document why the toggle was removed.

Design/Architecture Observations
5. SidebarResultsButton reads sessionStorage non-reactively — SidebarResultsButton.tsx:42

readHasOptimizeResults() is called directly in the render body. The value won't update if sessionStorage changes after the component mounts. This is acceptable only if the component always unmounts/remounts after optimization (e.g., full navigation). Worth confirming.

  1. hasOptimizeResults.ts casts without validation — hasOptimizeResults.ts:100

const parsed = JSON.parse(stored) as Route[];
return Array.isArray(parsed) && parsed.length > 0;
The as Route[] cast is fine for a boolean check since only Array.isArray and .length are used. No issue in practice, but worth noting for future callers that this doesn't validate the shape.

  1. Timeline connector min-h-[20px] may clip on tall stop cards — Sidebar.tsx:576-578

The connector uses flex-1 min-h-[20px]. If a stop card's content is shorter than the connector wants to be, it could appear detached. Verified visually before merge.

  1. Sidebar width jump: w-72 → w-[28rem] (288 → 448px)

The sidebar grew by ~56% in width. On 1280px-wide viewports this leaves ~780px for the map. Worth confirming this doesn't break layout at common screen widths.

Positive Notes
hasOptimizeResults.ts correctly guards against SSR with typeof window === "undefined".
Replacing the disabled with a in SidebarResultsButton is the correct accessibility pattern.
fill="currentColor" on SVG icons instead of hardcoded CSS vars is a good cleanup.
The module-level markerScaledSize lazy singleton in Map.tsx is a sensible optimization for the Google Maps Size object.
Edit mode banner moved from sidebar to a map overlay tooltip — cleaner UX.
Validation Gaps
The PR checklist has several unchecked items: format:check, npm run test, npm run build, all mobile checks, and all backend checks. The bug in item 1 above would be caught by a smoke test — recommend running at minimum lint, typecheck, and build before merge.

Summary
Two clear bugs to fix before merge: the always-visible "Save" button (#1) and the map pin anchor offset (#2). The Export button stub (#3) and hardcoded isSidebarOpen (#4) are polish issues. The timeline layout itself looks well-structured.

Copy link
Copy Markdown
Collaborator

@markboenigk markboenigk left a comment

Choose a reason for hiding this comment

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

The duplicate sequence badge is removed from EditableStopItem — condition met. Both bugs flagged in kirillakovalenko's review are non-issues in the current code (Save button is correctly gated, pin anchor is already translate(-50%, -100%)). CI is all green. Approved.

Kesar Sidhu and others added 10 commits May 27, 2026 11:43
Align the results header with the mock by using a compact app label plus Save/Export actions while preserving the existing sidebar toggle and pending-edit cancel behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Refine the sidebar title section, edit action, and footer copy styling to better match the hifi mock while keeping the route list behavior unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use route palette colors for map pins and switch marker visuals from plain dots to pin-style markers so map markers align with route styling.

Co-authored-by: Cursor <cursoragent@cursor.com>
Match the edit-mode layout with a wider results panel, save-edits CTA styling, and centered map status banner while keeping existing route behavior intact.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Add cyan timeline markers with dotted connectors in expanded routes.
Remove duplicate sequence badge from EditableStopItem.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@KesarSidhu KesarSidhu force-pushed the step3-edit-look-3-main-v1 branch from 9d416f4 to cf0e2d1 Compare May 27, 2026 18:43
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.

3 participants