Mobile-first /plan redesign: responsive shell + TripBuilder decomposition#31
Merged
Conversation
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebuilds the
/plantrip planner into a mobile-first responsive shell, decomposes the 900-lineTripBuildermonolith into a provider + pure components, and lands the full polish backlog plus an experimental draggable bottom sheet. This is the completedocs/PLAN-UX-REDESIGN.md(Phases 0–3); the design is recorded as ADR-076 indocs/DECISIONS.md.Why
On a 390×844 phone the old 55/45 split gave the builder a ~430px peephole (the 380px map alone nearly filled it) and starved the chat;
components/plan/had zero responsive styling. Ranger edits also landed invisibly in the other pane, and the trip window / delete / day-plan persistence had no UI at all. Now map, itinerary, and ranger are each usable full-screen, cross-pane updates are visible, and the trip lifecycle is complete.Phase 0–1 — the shell + decomposition
PlanShell.tsx— one client CSS grid:"itinerary map chat"onmd+, a single full-viewport pane behind a bottomPlanTabBaronbase. Everything mounts once; visibility is pure CSS (nouseBreakpointValuemarkup branch), so the Eve chat session and the maplibre canvas never churn on a tab switch (ADR-017 hydration-safe). Compressibleminmaxrails so the map never collapses on 768–780px portrait tablets.?pane=URL contract (from=graph → Ranger›?pane=›?trip= → Itinerary) with a surgical seed/fromreplaceState.TripBuilderProvider/useTripBuilder.tsxowns all trip state + ops (postOpwith uniform 401/429 handling,refreshTripthat preserves an unsaved day plan and defers a mid-drag refresh). Pure pieces:TripSwitcher,TripHeader,StopList,TripActions,TripInsights.TripBuilder.tsxis the thin composition used at every breakpoint.ChatPanelstays provider-free (window events only) so the/learnlesson player is unaffected.trailgraph:trips-changed(stream + settled fire) and a newtrailgraph:ranger-activityunread signal.cooperativeGesturesprop,getSource-guardedinstallLayersfix for the basemap-fallback wipe.tripmut(30/60s, writes) andtripread(60/60s, reads).Phase 3 — polish backlog (default-on)
setDatesop,YYYY-MM-DDnullable,endDate ≥ startDateguarded).DELETEroute.applyDayswritesstop.day; a reorder clears it) — plans survive reload.navigator.share→ clipboard fallback) and a tab alert badge./planchat reload persistence —:PlanTranscript(migration 029) +/api/plan/transcript, replayinginitialEventswith a dedup-ref seed so replayed turns don't re-fire events.Phase 2 — bottom sheet (behind
NEXT_PUBLIC_PLAN_SHEET, off by default)PlanSheet.tsx— a full-bleed map + a draggable itinerary sheet (peek/half/full snaps, velocity-projected settle, tap-the-handle to cycle forprefers-reduced-motion, native body scroll only at full); the Ranger becomes a FAB overlay. The flag is build-time → identical on server and client, so the layout branch is hydration-safe. The "over-drag the list atscrollTop 0grabs the sheet" handoff is deferred (needs iOS-Safari tuning); handle-drag/tap collapse ships first. The flag stays off until the mobile e2e is stable on the sheet.Testing
pnpm typecheckclean · 1035 unit tests (new pure coreschat-trips.ts+itinerary.ts#sameIdSet) ·next buildclean (flagged + default) ·eve info0/0.mobilePlaywright project +tests/e2e/helpers/pane.ts#openPane+plan-mobile.spec.ts(authed hydration gate —hydration.spec.tsruns anonymous and never renders the authed shell) +plan-phase3.spec.ts(dates / delete / persisted days / keyboard reorder / empty checklist). Full plan suite green in both projects against a seeded ephemeral Neo4j prod build; a flagged authed-hydration smoke confirmed the sheet renders clean.suggest_day_planfalse flash) were fixed before merge.Known follow-ups
The Phase-2 sheet is experimental (flag off): the
scrollTop 0gesture handoff and a shared-reveal-ref nicety in its second (hidden-on-desktop)TripBuilderinstance are noted in ADR-076.