Commit Graph

343 Commits

Author SHA1 Message Date
Maurice 32dfc75756 feat(tours): a city walk's arrivals and opening hours for the day it is on, at each stop in the planner and the detail (CW-02, CW-04)
A city walk now shows, at each stop, when the walk gets there, until when
the stay lasts, and what the stop's opening hours say about that visit. The
same lines appear under each stop row in the planner and under each stop in
the walk's detail, in the user's 12 or 24 hour format. A conflict names the
stop, the arrival, the end of the stay and the hours it was checked against,
for instance "Lenbachhaus closes at 18:00, during the stay from 17:20 to
18:20 (open 10:00 to 18:00)", in the warning colour. Nothing is changed by
these hints: no stop, order or route moves.

The times belong to one day the walk is on. Opened from a day of the plan,
the detail keeps that day, and checking stops off stays bound to it.
Opened otherwise, and in the planner, a small pill above the stops names
the day and its start, and the walk's other days can be picked from it; it
starts on the first day with a start time. The pick is only what is looked
at and is never saved, and another day never takes over the times quietly.
Without a day, a date or a start time the line says what is missing and no
arrival is shown. TREK keeps no time zone on a trip, so start, arrivals and
opening hours are all read as the local time of the plan, and an arrival
after midnight is said to be on the next day without being checked.

Opening hours come from the trip place a stop stands for, as the travellers
entered them, and otherwise from OpenStreetMap; a pill at each stop names
the source, and a notice says the hours are a hint to check. A stop without
hours stays unknown and is never shown as open, hours that are not in a
plain form are shown as written, and an arrival that is only a lower bound,
because a stay before it is not entered yet, is not judged unless no later
arrival could escape the conflict. A trip place that a stop stands for also
gives the stop its name before "Stop N".

The arrival at a stop is found where the route passes it in the walk's
order, so the end of a loop and a stop passed on the way out and back get
the right time. The rules live once in the shared package, for the server
to give the same answers. The walk's detail reads its stops again after a
save, its own or a teammate's.
2026-10-20 03:22:11 +00:00
Maurice 8c93dc8d9c feat(tours): show a city walk's progress on the phone's day row, and check its stops off offline (CW-03)
The day row on the phone now shows how many stops of a city walk were
visited on that day, "2 of 5 visited", like the desktop row does. Both rows
read it from one place, and a tap on the phone names it in full without
opening the row.

A walk's stops can be checked off, skipped and taken back without a
connection. The mark shows at once, waits in the offline queue and goes out
when the connection is back, in the order the marks were made and behind any
older mark of the same day that still waits. The day plan, the walk's detail
and a reload read the visits kept on this device with the waiting marks on
top, so a mark made offline stays on screen until the server has it. A mark
the server answers with "not found", because the stop, the day or the walk
was removed meanwhile, counts as done and holds back no later mark of that
day. Any other refusal, the Tours addon turned off among them, keeps the mark
as a failed change to try again from the offline settings. The visits are
read again when the connection comes and goes, and once more after the
waiting marks went out, so a mark the server dropped or refused leaves the
day plan. A trip's visits that answer after another trip was opened no longer
show there.

The offline sync keeps each trip's walk visits and reads the stops of a walk
this device has never opened, so it can be checked off offline too. A walk
whose stops this device could not read lists no stand-in stops and no count,
and says to open it again while online. A walk put on a day while offline
says its stops can be checked off once it has synced, instead of offering
buttons that cannot work yet. A mark that fails says to open the walk again
and try once more, in every language.

Marks carry no version, so the last one to reach the server wins, as with
the other changes sent after being offline. The offline guide says so.
2026-10-20 02:49:47 +00:00
Maurice fe78831bd9 fix(tours): a city walk's walking time, stays and total read apart and alike everywhere, and a stay plans no route again (CW-02)
A stay, a name, an importance or a protection set in a stop's dialog no
longer plans a city walk's route again: the walk stays ready to save, its
time overview follows at once, and one undo takes the change back without
routing either. A stop moved or added plans the route again as before. A
walk saves no breaks, so a cafe never counts as a stay and as a break at
once, and a break left from another type neither counts nor holds its save
up.

The planner and the tour detail show a walk's walking time, its stays and
their total apart and in the same words: 45 minutes of walking, a museum of
90 minutes and a cafe of 30 minutes make 2 h 45 min. A stay not entered yet
makes the stays and the total at least what is known, stays nobody entered
read not known yet, and stays entered as 0 read 0 min. A total entered by
hand keeps its own label, and the computed total shows beside it. The head
of the tour detail, the day row on the desktop and the phone, the tour
summary and the library of other trips show that same total, with a ≥ where
a stay is missing. Their time on the move is called walking, and the summary
says a walk is planned with its stays rather than breaks.

The tour list and the library carry the minutes a walk's stops are entered
with and how many have no stay yet, counted from the walk's points, so the
way back of a loop is no stop and its start's stay counts once. A loop run
the other way keeps its start as the stop there, with its key, name and
stay.

The planner's waypoint list keeps the rows of a leg in a file of their own,
and the tour detail its name heading in a part of its own, so both stay
within their size limits.
2026-10-20 02:49:47 +00:00
Maurice 961e2e4745 fix(tours): search along a tour through the places index along the line, and name what could not be searched (PLN-02, CW-05)
The search along a tour found nothing. It asked the places index for all
kinds of a stretch at once, above the 100 rows and 200 characters of terms
the index takes, so the index refused and every stretch went to the public
Overpass mirrors, which do not answer from this server. Now the index is
asked in small circles strung along the line, one request per kind and
circle within its limits, and an empty circle counts as an answer, so a
city walk lists its sights, museums, parks, cafes, restaurants and markets
in well under a second. The kinds the index does not know (viewpoints,
huts, drinking water, toilets and the like) are asked of Overpass along the
whole line at the same time, one query per stretch of up to 50 km, three at
a time, each with a short deadline of its own; a line past 400 km is
searched along its start and says so. When the index answers no circle at
all, its kinds go to Overpass beside the others instead of after them. A
kind no source could be searched for is named in a calm notice above the
list instead of reporting nothing found, and the reason is written to the
log. Unnamed taps, toilets, shelters, picnic spots, viewpoints, summits,
slipways and repair stands stay in the list and on the map under the name
of their kind; an unnamed garden, cafe or memorial is left out. The places
nearest the line are kept when there are more than sixty, listed from the
start, with the opening hours the source has.

A walk's parks are parks and gardens only, and its museums are museums
and galleries only, no longer the beaches, summits, theatres and cinemas of
the map's explore buttons; a water park the index files under parks is not
one of them. The index also answers markets and summits. The explore
buttons keep their single request, and a search of several kinds that
would exceed the index limits is asked one kind at a time instead of being
refused. The MCP tool search_tour_pois and its wiki row describe the walk
kinds and the new unavailable list, and the OVERPASS_TIMEOUT_MS row says
the search along a tour keeps its own shorter deadline.
2026-10-20 02:49:47 +00:00
Maurice 6d64ab1006 fix(tours): city walk gates: entity collection, formatting, a walk's name hint and the tests' visits repository
The day assignments entity carries the station visits that hang off it, as
the generator writes it. A city walk gets its own placeholder for an untitled
name, the tour service tests hand in the visits repository the service now
takes, and the files the walk touched are formatted. The theme icons of the
place search overlap by their start margin, so they stack the same way in
both reading directions.
2026-10-20 02:49:47 +00:00
Maurice 18695fbb1a feat(tours): a city walk's arrivals against its stops' opening hours, and a compact place search (CW-04, CW-05)
Opened from a day with a time, each stop shows its estimated arrival: the
start, the walking time shared out along the route, and the stays before
it, at the earliest while a stay is unknown. A stop whose opening hours say
it is closed then, or closes before the stay ends, says so with the times;
hours that cannot be read are shown as they are, and a stop without hours is
unknown, never open. The themes are a two by two grid and the categories one
line with a list to tick, so the search no longer fills the rail. The button
that discards a draft for a new tour says so in two words.
2026-10-20 02:49:47 +00:00
Maurice 255c141a92 feat(tours): fill a city walk from a theme: culture, parks, food or a bit of everything (CW-05)
The search along the route offers a walk's own categories (sights, museums,
parks, views, coffee shops, places to eat, markets) and four themes that set
them at once. A found place says which theme brought it, its source and how
far it lies from the line, straight across; taken in as a stop, it keeps its
name and opening hours. Nothing is taken in without the existing confirm.
2026-10-20 02:49:47 +00:00
Maurice e803d28bf1 feat(tours): check a city walk's stops off for the day it is on (CW-03)
The walk's detail opened from a day lists its stops in order, each with its
stay, importance and protection, and marks one visited or skipped for that
day, or takes it back. The day row shows how many were visited. Marks reach
the other travellers at once and change no route, place or order; a copy or
another day starts with none.
2026-10-20 02:49:47 +00:00
Maurice 5d65bbd03b feat(tours): plan a city walk with its stops, stays, importance and protection (CW-01, CW-02, CW-10)
City walk is a type of the planner: routed on foot without a hiking limit, on
the standard map. Each stop is edited in its own dialog, its name, its stay
(empty is not known, 0 a point passed through), its importance and whether a
proposed change must leave it; none of it plans the route again. The walk's
time is walking plus the stays, at least that much while a stay is unknown,
with no breaks on top.
2026-10-20 02:49:47 +00:00
Maurice adcaca3c5f feat(tours): bike tours in the contract and on the server (BIK-01 to BIK-06, RTE-01)
A tour can be a bike tour with a routing profile (touring, road, gravel,
mtb), stored per tour by a new migration. The server grades the ways of a
mountain bike route from OpenStreetMap (mtb:scale) through one shared
Overpass client, offers CyclOSM behind its own admin switch, and exports a
bike tour's GPX with the activity of its profile. A hike's route choices
are now exactly the three the card names: steep climbs, steps and ferries.
2026-10-19 21:33:40 +02:00
Maurice 827e682684 feat(tours): places along the tour, and a found place as a stop (PLN-02, PLN-03)
The editor gains a card under the waypoints: along the tour. It offers what
the tour type stops for as chips (a hike viewpoints, huts and shelters,
drinking water, food, summits, toilets, picnic spots, campsites, sights; a
paddle tour put-ins, boat rental and the like, the first three ticked) and
how far from the route to look, 250 m to 2 km. Only its button searches.
Each place found shows how far it lies from the route, straight across, and
where along the route; its pin is on the map in its category's colour, and
a click there opens it in the card. Opened, a place says its kind and
source, its address, opening hours as the source has them with a note to
check them, and its website. The answer says when it is out of date (the
route or the choices changed since), offline, failed, partly searched, cut
short at the first part of a long tour, or more than shown. Nothing about
the tour changes by searching.

An opened place can go in as a stop: after the point chosen, the one before
it along the route suggested, by the button alone, as one step undo takes
back. It becomes a stop of the tour on the place's spot, not a place of the
trip. A leg drawn by hand or a fixed line (a via ferrata, a portage) is not
cut: the point after which it would go says why and offers no button. Once
the new route is in, the card says what the stop added, as the difference
of the route planned before and after; while it is planned it says so, and
where either route could not be planned it says that rather than guess.

The search merges a place OpenStreetMap maps twice, as a point and as its
outline, by its name and spot. The library repository takes its offline
error from a shared online-only module, which the search uses too.
2026-10-19 16:24:59 +02:00
Maurice 692373c8b8 feat(tours): take a tour over from another trip, the dialog (LIB-02)
The Tours tab's list of the trip's tours gains a button beside the GPX
import: take a tour over from another trip. Its dialog lists the tours of
the user's other trips, searched by name and filtered by trip and type,
each with its trip and the measures it has (time, distance, ascent; one it
lacks is left out, a paddle tour's climb too). Choosing one shows it on a
map with where it comes from, its type, distance, time, heights and number
of waypoints, and the name it gets in this trip, its own name to start
with. The note under the name says the copy is a tour of this trip of its
own, on no day yet, and that later changes stay apart.

Only the button in the foot takes it over. The new tour then comes into
the trip's lists and map and opens in the editor, unless the editor holds
unsaved work, which it never replaces. Nothing is written before the
confirm, and closing writes nothing. The library is online only: offline,
or when the list fails, the dialog says so and offers to try again; a list
cut at 100 tours says to search or filter.

A tour taken over names its source in its provenance: "Taken over from"
with the trip and the tour as they were called then.
2026-10-19 15:28:53 +02:00
Maurice 9cd227fd81 feat(tours): fold the rail cards, remembered across reloads; trip totals as badges
The planner's cards fold to their head: waypoints, the paddle time estimate,
the wind and the checklist on the left, the open tour's summary on the right.
The title or the chevron folds a card, and the choice is kept in this
browser, so a reload finds the rails as they were left. A folded card still
says what matters in its head: the checklist what is open, the wind its day,
and the time estimate now its total as a badge, in the warning tone while
parts of it are unknown. The "planning values" badge and info dot of the
estimate go; what the starting values are is said once under its figures.
The obstacle entry dialog sits outside the checklist's body, so an obstacle
picked on the map still opens with the card folded.

The trip totals start folded to their counts and show each type's sums as
the row's white badges, each named in its tooltip, an incomplete one marked
as at least that much with how many tours it is known for. The info text is
shorter.

The Tours locale contract counts the 574 general keys the planned cards
brought in.
2026-10-19 14:18:28 +02:00
Maurice a87ce65899 feat(tours): the trip's tour totals by type above the tour list (STA-01)
The Tours tab's list of the trip's tours gains the filter the plan's tour
list has, and above the list a card with what the tours shown add up to:
how many, how many are on a day and how many not, then per type distance,
ascent and descent, and the three kinds of time apart, the router's for
tours planned in TREK, the one an import brought, and the planned one with
breaks. Nothing is added up across types. The filter narrows the list and
the totals alike.

Each tour counts once however many days it is on; the list is one row a
tour. A value no tour has is left out rather than shown as zero, and a sum
some tours lack is shown as at least that much, its info dot saying for how
many of how many it is known. Paddling sums no heights: on the water a climb
says nothing, and a planned paddle tour's heights would be the banks'.

The card folds to its counts, remembered in this browser. The empty state
for a filter that leaves nothing is shared by both lists now.
2026-10-19 13:55:07 +02:00
Maurice 06e6e25b25 feat(tours): OpenHikingMap as a hiking base map of the tour planner (MAP-01)
While a hike is planned, the planner's map switch offers "Hiking" beside the
map, topo and satellite: OpenHikingMap, with marked trails over the terrain.
It is a choice of the planner's view alone, like topo: the global map
setting, the tour and its days stay as they are. With no tour open, over an
import viewed as it came in and for a paddle tour it is not offered, and a
choice made earlier falls back to the standard map there.

openmaps.fr's tile usage policy is followed: tiles load only as the map
shows them, with the browser's Referer, from the server's own caching; no
service worker rule keeps them and the 3D flyover's warm-up passes their
source by. Its credit and donation link are on the map; the 3D map, whose
attribution is folded away under the panel, shows them as a line of its own
above its controls.

The service is best effort. A run of failed tiles while it is shown marks
the switch, with a tooltip and a status for screen readers that say it is
not answering and that the tour is untouched; one tile arriving clears it.
The tile health the seamark overlay had is now useTileHealth, shared by both.

The source is free for non-commercial installs up to 500,000 tiles a month.
tours_hiking_map_enabled is an admin switch under Tours (admin tours-hiking-map,
audited), on by default, for an install that is commercial or larger to
switch off until it has an agreement with the operator. /api/addons carries
it as toursHikingMap, true only while Tours is on.

Leaflet, GL and the 3D map read one table of the planner's raster bases
(tourRasterBases), so topo and the hiking map are drawn the same way.
tile.openmaps.fr is on the CSP's connect-src for the GL maps.
2026-10-19 13:07:36 +02:00
Maurice ad86713fdc feat(tours): route choices for a hike, each checked against the router (MF-08)
A hike can ask the router for more than its difficulty limit: avoid steps,
avoid ferries, prefer footpaths, shorter over faster. They sit under the
limit in the planner's details as switches, each with what it really does,
and the info dot says they weigh the way and give way where there is no
other, and that none grades a path. Switching one plans the route again as
one step of the history, and the choice is kept in the draft.

Only preferences the public Valhalla was seen to honour are offered, with
the measured cases beside hikingCostingOptions: step_penalty took Würzburg
to the Festung from four flights to one, use_ferry 0 sent Kiel round the
Förde and Hamburg through the Elbe tunnel, walkway_factor moved Garmisch to
the Partnachklamm onto the paths, shortest cut the way to the Eckbauer.
use_hills and use_tracks showed no effect on foot and are left out, as are
marked, paved and rough ways, for which the router has no option.

tours.hiking_preferences (migration 045000) holds them as JSON, NULL for
none, so no tour saved before routes differently. Only a hike keeps them;
a paddle tour naming one is refused. A copy carries them, and list_tours
and get_tour_plan read them.

The trip copy's waypoint links now follow the copied places inside
TourWaypointsRepository.insertForPlace.
2026-10-19 11:31:31 +02:00
Maurice 7a484a09d4 feat(tours): stops that stand for places of the trip (PR1-10)
A tour's waypoint can stand for a place of its trip, chosen on purpose from
"Trip places" in the planner: searchable, nearest to the tour first, grouped
into near the tour and the rest, and a place already in the tour says so. A
pick adds the stop on the place's spot as one step of the history; the row
names it after the place and says it is a place of the trip. The point keeps
its own coordinates, the place stays a place of its own and its days are
left alone. Moving the point or "Unlink from the place" drops the link;
removing it never touches the place.

tour_waypoints.linked_place_id (migration 044900) references places with
ON DELETE SET NULL, so a deleted place only unlinks. A save checks the links
inside its transaction: a tour of the trip is refused, a place that is gone
or of another trip leaves the point unlinked, the same either way. The trip
copy points the links at the copied places, the GPX export writes the linked
stops as named waypoints, and get_tour_plan names them.

nearnessToLine in @trek/shared measures a point against a route, for the
picker and for the search along a route that comes next.
2026-10-19 10:52:26 +02:00
Maurice d72352911e feat(tours): tour revisions, conflicts and a live editor (P2C-03)
A saved tour now has a technical revision, raised inside the transaction of
every write that changes it: the route and its controls, the plan laid onto a
recorded paddle track, going back to that track. A write that names the
revision it was based on (expected_revision) is refused with a 409
{ code: 'tour_revision_conflict', revision } before anything of it is
written, so a stale draft never overwrites a newer tour unseen. A write that
names none writes as before, so older clients and queued offline writes keep
working; the queue never carries a base. A copy starts at 1, a source's
version stays provenance. Migration 044800 adds the column; list_tours and
get_tour_plan read it.

The editor follows the trip's tours live: a newer revision of the open tour
loads at once while the editor has no changes of its own, and shows a notice
while it has. A refused save keeps the draft and asks: save it as a new tour,
load the newer version, or overwrite on purpose.

useTourPlanner was at the size limit; its derived facts, undo history and
draft storage move into tourPlannerFacts, usePlannerHistory and
useTourDraftStorage, unchanged in behaviour.
2026-10-19 10:22:04 +02:00
Maurice 134ab64bce feat(tours): download a saved tour as a GPX file (PR1-06A)
A saved tour can be handed over as a GPX file on purpose: its whole saved
line as one track with the heights it has and none it lacks, its name,
description and link, and the activity in <type>. The file is named after
the tour. A tour without a line of two points is refused with 422 rather
than written as a file that imports as nothing; the export changes nothing.

GET /api/trips/:tripId/tours/:placeId/export.gpx, readable by anyone who
sees the trip, and the MCP tool export_tour_gpx with the same rules. The
tour detail gets a "GPX" action beside the navigation, the planner head a
download button that waits while the tour has unsaved changes.

The tours rail head now uses the same plain icon buttons as the editor.
2026-10-19 09:42:13 +02:00
Maurice 1bc82f97fd feat(tours): route paddle tours on the water, shaping points and auto-loaded regions
Paddle tours are planned on the water by TREK's own router: a water network
per paddle region, built from the same Geofabrik extract as the obstacles and
searched in a worker thread of the server (no sidecar). Rivers, canals and
lakes (direct or along the shore), portages round weirs, locks by policy,
whitewater by boat, gaps marked. Found portages and locks become points of
their own; an unplannable leg says why and offers a way out.

- Shaping points: a click on the line sets a point that steers the route
  without being a stop (hikes and paddle tours); recompute a single leg.
- Lake style direct/shore, suggested from the wind forecast.
- Regions load by themselves where a paddler plans (admin setting: automatic,
  on request, off; size cap and a daily count), with requests for the admins,
  a notification, and the load followed on the leg.
- Portage from the last point, portages follow footways via the walking
  router (or stay straight), "put in here" on slipways and put-ins.
- MCP plan_paddle_route with the REST route's rules.
2026-10-18 21:21:32 +00:00
Maurice 532010aa79 feat(journey): the journal settings list who a linked trip lets in
Under the contributors, the journey settings on desktop and phone get a section of their own, Through trips, with everyone a trip's journal link lets in, their role and the trip they come through. It is read only there, since the trip's settings manage it, and it leaves out whoever is a contributor already. getJourneyFull answers it as trip_access.
2026-10-18 22:04:41 +02:00
Maurice fe05afec19 feat(trips): trip settings with a linked journal tab
The Share button becomes the trip's Settings, a round button beside the back
pill. The dialog is rebuilt around three areas (People, Sharing, Journal) with
a side navigation, a fixed height and 960 px width on wide screens.

Journal links one of your journals from the Journey addon to the trip. Every
trip member is ticked as a reader by default, each can be raised to editor or
left out, and the people a save would let in for the first time are named
before it saves. The link can be changed or removed. With a link the trip gets
a Journal tab on desktop and phone that shows the Journey addon's own view,
live through its sync and trip:journal:changed. Nothing shows with the addon
off.

members.shareTrip and nav.share are gone with the button that used them.
2026-10-18 17:41:25 +02:00
Maurice 80b6739362 feat(journey): a trip can link a journal and open it to the members it picks
A trip can now show one journal from the Journey addon as its own: any
journal its owner picks, and one journal on as many trips as they like.
The trip members chosen for the link get into the journal as viewers or
editors, see it in their own journal list and follow it live, for as long
as the link holds them and they stay on the trip.

That access is never copied into journey_contributors. It is read where
journal access is read: the contributor repository answers with the
stronger of a direct role and a link role, the journal list and the live
update recipients take the link members in, and the photo access check
goes the same way. Every one of those reads starts from linkReach, which
only counts members still on the linking trip, so unlinking, deselecting
someone and their leaving the trip all end exactly what the link gave.
A member who leaves is also taken off the link, so coming back later does
not quietly reopen the journal.

Linking or changing the members takes the journal's owner and the new
journal_link trip permission (trip owner by default); unlinking takes
either. /api/trips/:tripId/journal answers the link as each member may see
it, /candidates says who a journal would be opened to for the first time,
and four MCP tools do the same over the same service. A trip:journal:changed
event tells the trip to look again.
2026-10-18 15:59:33 +02:00
Luffy d229613e0e fix(journey): add localized error messages for dismissing suggestions 2026-10-18 14:04:22 +02:00
Maurice 23b28a1f3f feat(packing): drag a category by its head to move it among the others
Categories showed in the order they were created, which a list kept per day
cannot undo once the days swap. A grip in each category's head band moves
the whole category onto another's place on desktop. A category has no
position of its own, it shows where its first item is, so the move reorders
the items as one block through the item reorder the list already has: no
new column, and the order reaches everyone the way a dragged item does. The
other view's categories keep their order.
2026-10-18 13:21:54 +02:00
Maurice bfec874d04 fix(i18n): mention backup codes in the disable-2FA hint for every locale 2026-10-18 11:47:11 +02:00
Maurice 5ee8d450a9 refactor(i18n): the checklist's drawing hint goes, nothing in the planner shows it 2026-10-17 01:16:41 +00:00
Maurice fa8272c522 feat(i18n): the paddle checklist and safety strings in every language
The checklist, its statuses, choices and notices, and the safety note of a
paddle tour, translated into all 27 languages. A spec keeps the checklist
strings in English and German from claiming the water is safe, cleared or
passable. The paddle strings of the last batch that Prettier had not seen
are formatted.
2026-10-17 00:29:18 +00:00
Maurice 1e2ba0f842 feat(i18n): the paddle portage, time, wind, obstacle and region strings in every language
The strings of the paddle plan, the time estimate, the wind card, the obstacle card and notice and the admin's paddle water data, translated into the 25 locales that still lacked them, with the plural forms each language needs. The pinned count of Tours keys follows.
2026-10-16 23:22:09 +00:00
Maurice 03d6457bde feat(tours): paddle obstacle card, admin regions panel and obstacle marks on the route band
PAD-05B: a click on an obstacle on the map or on the route band opens its card in the look of the via ferrata card: the kind with its glyph, the name, how it stands to the route (on it at a distance along it, near it with the link marked unclear, or only in the area), the paddling rule its tags give with canoe read before boat, a condition as written, height, grade, hours and fees, the source with the date of the data and the OpenStreetMap link. A missing rule reads as unknown, never as allowed, and a portage way recorded as private says so. Objects only in the area show from zoom 13 on, on Leaflet and GL alike; on GL the lines only near the route are dashed as on Leaflet, one click handler picks the marker over the line, and a picked marker no longer flickers. The route band marks the obstacles on and near the route by their share of the measured line. The obstacle notice also names an answer cut at its limit.

PAD-05A: the admin area gets a Paddle water data card under the addons, on desktop and phone: a search in Geofabrik's list with each region's path, the regions with their state (waiting, reading with its progress, ready with objects and data date, failed with the reason), reading again and removing after a confirmation. The list follows a read without reloading. Region changes write audit rows.

Map colours of paddle objects and portages come from theme tokens read at draw time, as the via ferratas do; the ferrata layer now shares that reader. The rail takes the planner page's parts as one bag, the map hit tests of the tour layers are one helper, and the unused noWaterData string is gone from every locale.
2026-10-16 23:03:09 +00:00
Maurice 9494521ac7 feat(tours): plan paddle tours, hand-drawn legs, reverse and return to start, maps per tour type
- Paddle as a plannable tour type: one boat (kayak, canoe, SUP, other), river or
  lake, a pace that a boat change never overwrites; time is distance over pace
- Hand-drawn legs beside routed ones, drawn dotted and labelled as not routed,
  kept through save, reopen and edits elsewhere
- Reverse a tour and close it back to its start, each one undo step
- GPX import shows a preview first (line, measures, duplicates, type) and only
  the confirmation stores the tour
- Base maps and overlays per tour type in the planner: hike keeps topo and the
  via ferrata layer, paddle gets the OpenSeaMap seamark overlay
2026-10-16 23:14:52 +02:00
Maurice 485e360c64 Tours: save a tour as a new, independent tour (P2C-07) 2026-10-15 22:18:41 +02:00
Maurice cd1b1410bd Tours: filter a tour list by source, routing limit and type where it varies (PR1-13) 2026-10-15 22:02:41 +02:00
Maurice 3d9095ccde Tours: provenance contract, source check, one assignment path and the map overview
- P2C-02: tours record their origin (planned, GPX with file name, wanderer)
  instead of reading it off their shape; the detail answers a provenance
  contract and a trip copy keeps a tour's import record
- MF-03: a wanderer snapshot's source can be checked on purpose, read only,
  with a confirmed reimport as a new snapshot
- PR1-18: every way of putting a tour on a day shares one set of rules
- PR1-07/08: each person can hide tours from the trip map; the list shows
  each tour's line colour and the picked tour stands out on both maps
2026-10-15 21:51:22 +02:00
Maurice 782e613506 Tours: day GPX import, wanderer trails and planning over an import
- GPX files drop onto the map or a day; the import lands on that day
- wanderer connection per user in Integrations; the workspace offers the
  user's own trails only, behind an admin switch under the Tours addon
- wanderer difficulty is stored on the SAC scale (T1 to T3), backfilled
- a GPX or wanderer import can be planned as an editable tour, either in
  place (the recorded track is kept and can be restored) or as a new tour
  that remembers the import it came from
- rails, rows and detail dialog follow the plan sidebar's cards and badges
- admin addon shelves with more than one row fold, collapsed by default
- reverse-geocoded waypoint names are cached on the device
2026-10-15 17:44:15 +02:00
Maurice d118c3cee9 chore(tours): drop the planner strings nothing shows any more 2026-10-14 21:09:05 +02:00
Maurice 84d637f5fe feat(tours): via ferratas on the tour as fixed legs of their own line, crossing warnings, violet ferrata look, tour list and editor polish 2026-10-14 20:21:39 +02:00
Maurice 6d43f3a4e6 feat(tours): hiking-rule walking time, source marks in the map search, tour rows and status badges reworked, ferrata card in the map glass 2026-10-14 20:21:39 +02:00
Maurice e3983ef857 feat(tours): tidy the tour editor and tour list, set points only on purpose, name waypoints on the map 2026-10-14 20:21:39 +02:00
Maurice 160bc89e78 feat(ferratas): keep loaded via ferratas in a tile cache on server and device, group segments, own look and count badge 2026-10-14 20:21:38 +02:00
Maurice a9882a6415 feat(tours): via ferrata layer mounted on the tours map (2D and 3D) 2026-10-14 20:21:37 +02:00
Maurice 98cc57942b feat(tours): 3D terrain view with flyover and grade colours, imported tours carry no hiking difficulty
The tours map gets a 3D mode on the same map surface between the side panels:
a "3D" switch in the layer pill drapes the route over open Terrarium elevation
tiles (AWS Open Data), colours it by grade, plays a flyover tied to the
elevation profile in the rail, and keeps planning working by clicking and
dragging waypoints on the terrain. The corridor around the route is preloaded
before the flyover so the landscape never loads in front of the camera.

GPX imports no longer get a made-up hiking difficulty: max_hiking_difficulty
becomes nullable (new migration, waypoints kept), the import writes null and
the client shows no T badge for it. Drawn tours still default to T2.

Info hints in the planner show their tooltip only, and the discard
confirmation reads "Discard changes".
2026-10-14 14:02:27 +02:00
Maurice 3c8fa07f44 fix(admin): show when users were last active and keep the list current
The column showed the last sign-in, which a renewing cookie leaves weeks
behind for someone using TREK daily. It now shows the later of the sign-in
and the last request. Saving an edit no longer blanks the row's avatar,
activity and online dot, and the list refreshes every 30 seconds while open.
2026-10-14 13:24:27 +02:00
Maurice 07a82be64e fix(tours): short save and discard labels, info hints level with their label 2026-10-14 11:11:48 +02:00
elmocito eb13d9f785 fix(i18n): add Tours locale keys 2026-10-14 08:39:31 +02:00
Maurice 8a8c3e4c64 style(i18n): prettier on the translation files this branch touched 2026-10-12 21:22:36 +02:00
Maurice 2777773f7b fix(dayplan): the delete day question says its bookings keep their date
Deleting a day said its bookings stay under Bookings without a day, which
read as if their date went too. They keep their date and stay listed,
upcoming ones included; the hint now says so.

Refs #2604
2026-10-12 20:43:00 +02:00
Maurice d4f4ab3891 fix(bookings): the delete question for a booking with a linked expense says the expense is deleted too
Deleting a booking also deletes the expenses linked to it, but the
question only said the booking would be deleted. A booking with a linked
expense now says so in every place that asks: the bookings list and detail,
the transport and transit dialogs, and the phone's booking cards. The MCP
delete_reservation description names the linked expenses and the stay a
hotel booking created as well.

Refs #2604
2026-10-12 20:42:55 +02:00
Maurice 62a80f420c fix(bookings): an end time before the start time on the same day shows a warning in the booking dialog
A booking saved with 18:00 to 09:00 and no end date was stored as ending
earlier on its start day without a word. The dialog now says that the end
time lies before the start time and that an end date is needed if it ends
the next day, on desktop and on the phone. It only warns and does not block
the save, since time zones can make such times correct.

Refs #2604
2026-10-12 20:42:48 +02:00
Maurice bdd8c08dd4 fix(planner): places put on a day, day names, day notes and trip details changed offline wait in the queue and sync once the connection is back
The day plan wrote straight to the API, so offline a place dropped on a day
snapped back with "Error assigning place", a renamed day or a new day note
failed, and a moved stop, a leg's travel mode or who joins a visit were lost.
Visits (put on a day, taken off, reordered, moved, travellers, leg mode), the
day's name, notes text and travel mode, and the day notes (add, edit, delete,
move) now go through assignmentRepo, dayRepo and dayNoteRepo and the mutation
queue: the cached day changes at once, a visit or note made offline gets a
temporary id that the edits after it wait for, and an online write held behind
an older queued one joins the queue, since none of these carry a version
token. A new order of a day that names a visit made offline is sent with its
real id, or without it when its create failed. Desktop, the phone timeline and
note sheet all write through the store, so both are covered.

The replay reads each answer for what it names: the day answer keeps the
cached notes and visits, the participants answer lands on its visit, and a
visit the server refuses with 409 (a Tour already on that day) fails instead
of waiting as a conflict no retry can solve.

The trip's name, description, reminder and the archive flag wait in the queue
too, from the planner, the phone and the dashboard. What only the server can
do says so instead of failing: new dates, a day count, a currency or a cover,
a new trip, a copy or a delete, members, guests, share and invite links, and
a new order of the days, which moves the dates of the bookings.

Refs #2601
2026-10-12 20:17:57 +02:00