Saving & Loading Routes
Relevant source files
The following files were used as context for generating this wiki page:
The "Saving & Loading Routes" system allows users to capture a complete snapshot of their planned trip, including the route polyline, waypoints, search filters, and discovered Park4Night spots. This feature is designed to allow users to reload complex plans without re-querying external APIs, facilitating offline-ready or persistent trip planning.
Sources: src/lib/savedRoutes.ts:1-7, src/components/Planner.tsx:391-397
Architecture and Data Flow
The system operates primarily on the client side, using localStorage for persistence via a central application state. The architecture is divided into pure domain logic for managing snapshots and React components for user interaction.
State Persistence
Saved plans are stored within the AppState under the plans array. The application uses a loadState and saveState pattern to synchronize this array with localStorage under the key p4n-map:v1.
Sources: src/lib/settings.ts:24-34, src/lib/settings.ts:63-70
Logic Flow for Saving a Plan
When a user saves a plan, the system captures the current Planner state and creates a SavedPlan object. This object is then prepended to the local list, which is capped at a maximum of 30 routes.
Data Structures
The core of the system is the SavedPlan interface, which contains all the necessary data to reconstruct a map view and results list without network calls.
SavedPlan Schema
| Field | Type | Description |
|---|---|---|
id | string | Unique UUID for the plan. |
name | string | Human-readable label (defaults to "Start → End"). |
createdAt | number | Timestamp of creation. |
stops | Stop[] | List of trip waypoints (A, B, C, etc.). |
specs | Specs | User preferences like min rating and required services. |
corridor | CorridorSettings | Distance settings for searching along the route. |
route | RouteSummary | The polyline and distance/duration data. |
spots | ScoredPlace[] | The Park4Night spots discovered during the original search. |
Sources: src/lib/types.ts:153-166, src/lib/savedRoutes.ts:26-30
Key Components and Functions
Domain Logic (src/lib/savedRoutes.ts)
createSavedRouteSnapshot(input): Transforms raw planner input into a structuredSavedPlan. It generates a random UUID and derives a default name from the first and last stops.addSavedRoute(plans, snapshot): Handles the immutable update of the plans array, ensuring the most recent plans appear first and enforcing theMAX_SAVED_ROUTESlimit.renameSavedRoute(plans, id, name): Updates the name of a specific plan while preventing blank names.
Sources: src/lib/savedRoutes.ts:35-49, src/lib/savedRoutes.ts:57-70
User Interface Components
The project provides two primary interfaces for interacting with saved routes:
- Sidebar Component (
src/components/SavedRoutes.tsx): A compact list shown within the Planner sidebar. It allows quick loading of snapshots or deletion. - Routes Page (
src/app/routes/page.tsx): A dedicated management view (Accessible via/routes) that allows users to:- Rename routes through an inline editing mode.
- View detailed metadata (creation date, distance, number of spots).
- Delete routes.
- Open routes on the map using a deep-link query parameter (
/?load=<id>).
Sources: src/components/SavedRoutes.tsx:5-15, src/app/routes/page.tsx:75-120
Loading Mechanisms
There are two primary ways a saved route is reloaded into the application:
1. Direct Selection
In the Planner component, the loadPlan function retrieves a plan by ID and applies its snapshots to the active state. This immediately updates the map polyline, markers, and results list without triggering new API requests to Park4Night or OSRM.
Sources: src/components/Planner.tsx:432-442
2. Deep Linking
The system supports loading via URL parameters. When the application hydrates, it checks for a load parameter in the URL.
Summary
The "Saving & Loading Routes" feature provides a robust local-first caching mechanism for trip planning. By snapshotting the entire state of a plan—from the geometry of the route to the specific services found at each spot—users can manage multiple itineraries efficiently. The system enforces a 30-route limit and leverages client-side storage to ensure that user data persists across sessions without requiring a complex backend database for initial use.