Commit Graph

19 Commits

Author SHA1 Message Date
Maurice b7951baf23 fix(ci): green the dev gates after the native and popup rounds
- RTL: the measured pills and centred controls use logical forms or a marked line
- i18n: the two native widget numbers are positions, not counts (NOT_PLURAL)
- Types: styleOverride on the lazy GL map, the location and shared-file payloads,
  the capabilities fallback, the transport sheet's stay metadata
- ESLint: latest-value refs move to layout effects, usePresence keeps the last
  open state in state, the booking import opens clean with a shared document
  kept in the list (the reset effect used to clear it again)
- Layers: the phone import sheet lives under mobile/ and reads through tripRepo;
  the offline host check moves to utils/tileUrl
- Sizes: plugin layer geometry, hardNavigate and the exit animations get
  modules of their own
- Tests follow the status radios, the stay chip overview, the dock + button
  for the first list and the field token; store registry lists the new stores
2026-11-06 18:24:25 +01:00
Maurice def8b8a24d release notes: the 5.1.0 popup, and dataforest cloud in Settings > About
The release popup now shows 5.1.0: place search, shared place details
and faster routing as three cards side by side, each with its own
drawing. The support band is set as a card like the promise above it
(optional supportLabelKey; a release without it keeps the plain line),
and the two support buttons get the same glass look in their colours.

Settings > About gets a full-width panel for dataforest cloud, who
sponsor the servers behind place search, address search and routing.
Both logos ship in client/public/brands, so opening Settings reaches no
third party. Wherever a line names dataforest cloud it links to
https://cloud.dataforest.net/?mtm_campaign=trek, the link dataforest
gave us; the README moves to it too.

All 28 locales carry the new copy, and the old 5.0 card keys are gone.
2026-10-31 11:04:19 +01:00
Maurice 390135f3bc feat(demo): a new welcome dialog for the demo, in the 5.0 dialog style
The old popup was a narrow white card with its own copy of the texts in
eight languages, hex colours and a minute counter on the browser clock. The
new DemoWelcome is a wide dialog on DialogShell with theme tokens only: what
TREK is in one line, the hourly reset with a live countdown in the server's
time zone, the 5.0 highlights to try right away (trip planner with bookings
and costs, Tours with 3D terrain, TREK Studio photo books, live
collaboration, Journey, Atlas, Vacay, Collections, offline use), what the
demo leaves out and what the full version adds, and the link to the source.

Its strings are real i18n keys in a new demo domain file, translated into
all 27 locales. Both dashboards open it instead of the old DemoBanner, which
leaves the theme and format baselines with its file and the test non-null
assertions it held.
2026-10-24 23:22:15 +00:00
Maurice 1696162d22 fix(deps): maplibre-gl 6.15.0 past the attribution sanitizer advisory
GHSA-jrc7-96c5-q579 covers every maplibre-gl up to 6.4.0 and has no 5.x
release, so npm audit kept flagging the patched 5.24.0. Moving to 6.15.0
retires the local backport: patch-maplibre.mjs and its postinstall,
predev and prebuild hooks go, along with the Dockerfile copy and its
format-baseline entry. 6.x sanitizes attributions against an allow list.

What the major changes for TREK:
- ESM only, no default export: the engine module imports the namespace
  and hands that out as its default, so every caller stays as it was.
- The worker is no longer inlined, and inside a bundle MapLibre cannot
  find it next to its own module. The engine sets it from Vite's
  ?worker&url build before any map, the Leaflet bridge's included.
- WebGL2 only: the probe asks for webgl2 alone, so a WebGL1-only browser
  gets the raster basemap instead of a GPUInitializationError.
- 6.9 shapes right-to-left text itself and deprecated setRTLTextPlugin;
  the old plugin would replace that and could only run through eval in
  the module worker, so MapLibre no longer registers it. Mapbox does.

The lockfile moves maplibre-gl and its own dependencies only; the
Leaflet bridge already allows ^6.0.0 as its peer.
2026-10-24 22:41:56 +00:00
Maurice 35566690e9 feat(places): the picture of a place is chosen in the editor, and the view opens its photos
- The editor's 'Pick a picture' is the one place a place's picture is set, on
  the desktop dialog and the phone sheet alike: upload one from the device,
  keep the current one (now shown as chosen), take an image attached to the
  place, or one of the sources' photos, or remove it. Nothing is sent before
  the save: the upload and the attached file are put in place once the place
  is saved, so Cancel leaves the picture as it was and a new place can get
  one too. Without the details column the same picker sits in the form.
- The view (inspector and phone sheet) shows the picture plainly; a click opens
  the gallery of its own picture and its sources' photos.
- The gallery drops an answer that arrives after the place changed, and its
  credits link to their source pages. The lightbox is a labelled modal dialog
  that takes and gives back focus, names its arrows and follows the reading
  direction.
- The picker leaves the details column (PlaceImagePicker), the column reads
  the shared enrichment cache, and PlaceAvatarUpload and usePlaceImagePick,
  which only the view used, are gone.
2026-10-23 21:01:11 +02:00
Maurice f5197159f7 chore(ci): baselines follow the Studio code that moved to shared 2026-10-22 21:34:16 +00:00
Maurice cdb473d427 fix(ci): keep the Studio files on the format baseline until the wave that moves them lands 2026-10-22 21:34:15 +00:00
Maurice 4a782c6d07 chore(client): the charging info is formatted now, off the format baseline 2026-10-22 21:34:15 +00:00
Maurice 984ee67517 feat(assistant): journal entry cards, and markdown stripped in shared 2026-10-22 21:34:15 +00:00
Maurice d2a2728cde feat(studio): the book engine in shared: layouts, grids, page ops and findings 2026-10-22 21:30:39 +00:00
Maurice b64da26651 feat(assistant): trip assistant chat with your own AI connection
Adds an in-app assistant that reads and plans the open trip. Users connect
their own provider (Sign in with ChatGPT, or an Anthropic, OpenAI, Gemini or
OpenRouter key) or use the one the admin set up, including a custom
OpenAI-compatible server. It is an addon and only shows while a connection
is usable.

The chat runs on the existing MCP tools, pinned to the trip. Every change is
held as a change card the user applies or discards, and applied changes can
be undone. On the desktop it is a floating window that can be moved and
resized; on the phone it is fullscreen. Search results show as place cards
that can go onto a day, weather lookups as a strip, proposed places as
ghost markers on the map with a before/after switch, and an answer can be
shared into the trip chat. Booking files can be dropped in and are read
into change cards.
2026-10-22 21:30:12 +00: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 aeaf3693ad fix(mascot): typecheck the clip metadata and keep the client ratchets green
The tuple cast on clips.meta.json failed tsc. The clip lookup and the 3D
opt-out move into mascotClips.ts so the component file only exports the
component, the crop offset is allowed as a deliberate physical side, and
MDancingTrek leaves the format baseline.
2026-10-11 21:33:31 +02:00
Maurice 242756708e ci(client): run theme:lint as a per-file ratchet with the missing token rules
theme:lint only reported a total and exited 0, skipped whole files by name and
never ran in CI. It now counts per file under src/ against
scripts/theme-baseline.json, which only shrinks, like lint:rtl: the colour
literals, arbitrary colour classes and numeric font sizes it already saw, plus
palette classes (bg-gray-100, text-indigo-600, bg-white), raw text sizes
(text-sm, text-[13px]) instead of the type tiers, z-index literals above z-50
instead of a step of the layering scale, and reads of the dark_mode setting.
The file exemptions are gone; the map, PDF and brand files carry their count in
the baseline instead. theme-lint-disable markers stay valid in a comment and
are counted against scripts/theme-disable-baseline.json, like rtl-lint-disable
in lint:rtl; a new one raises its file's entry by hand, where review sees it.
The comment handling lint:rtl already had moves into scripts/lib/source.mjs so
both read source the same way.
The check runs in the client-quality job.
2026-10-10 21:32:05 +02:00
Maurice 5fcb307270 test(client): hold the default MSW handlers to the @trek/shared contracts
contractHandler() parses the request body against the shared request schema,
answering 400 like the server's Zod pipe on a body it would refuse, and the
mock's answer against the response schema, failing on a factory that drifted.
The trips, budget, places, todo, tags and categories, day notes, packing,
reservations and assignments handlers and the vacay plan and colour updates use
it wherever shared has a schema; the offline bundle and the other vacay routes
have none yet and stay plain.
The typed bodies showed where the old handlers echoed request shapes back as
stored rows: payers and members are no longer echoed into a budget item, and
checked and is_private come back as 0/1 the way the server stores them.
2026-10-10 21:31:34 +02:00
Maurice e971c41d1a chore(client): delete the old budget panel components that only their own tests still imported
BudgetPanel, its summary, category table, inline edit cell, add row, per person
line, pie chart, ring avatar and the useBudgetPanel hook were replaced by the
costs panel and nothing outside their own tests imports them any more.
BudgetPanel.constants, BudgetPanel.helpers and BudgetPanelMemberChips stay in
use. The rtl, format, offline and eslint baselines drop the deleted files.
2026-10-10 21:31:33 +02:00
Maurice 2ccdba78d6 chore(client): lower the ratchet baselines after sharing the feature hooks
The size, layers, format and eslint baselines only go down: files that
shrank, moved or lost a copied warning leave or lower their entries.

The offline baseline drops from 212 to 170 entries. 102 desktop and phone
views no longer import src/api/ and leave the list. 60 shared hooks take
their place, because the calls those views made moved into the one hook
both of them now import. Each of the 60 is imported only by views that
were on the list before, and every api module it imports was imported by
those views before. No call is new, and none moved behind the repo or the
mutation queue, so the offline behaviour is the same as before.
2026-10-09 15:20:09 +02:00
Maurice ead327be73 ci(client): lint:format covers the Playwright specs and the client scripts
The check only looked at src/ and tests/, so a new spec under e2e/ or a
new script under scripts/ could land unformatted, and the ratchet scripts
themselves did (fixed in the previous commit). It now walks e2e/ and
scripts/ too and takes .mjs alongside .ts, .tsx and .css. The 58 files
there that were unformatted before this branch (the e2e specs and help
guides, the older build and lint scripts) join the baseline, which keeps
only shrinking; JSON baselines stay out of scope.
2026-10-08 13:04:40 +02:00
Maurice 37d386178b ci(client): lint:format keeps new client code Prettier-formatted
client/package.json has had a format:check script, but no workflow runs
it, and 2144 of the 2171 .ts, .tsx and .css files under src/ and tests/
differ from what .prettierrc asks for. Without a formatter gate the line
count in lint:size could also be gamed, and every new file picked its
own layout.

Formatting everything in one commit would bury the history, so lint:format
lists today's unformatted files in scripts/format-baseline.json and only
lets the list shrink: a file outside it, any new file in particular, must
be formatted, and a listed file that has been formatted must leave the
list (--update takes it off and never adds one). A stale entry fails the
check, since it would let the next file at that path in unformatted.

The check runs Prettier through its API with the config that applies to
each file and reads the text with LF line ends, so a Windows checkout
agrees with CI about endOfLine. A file Prettier cannot parse counts as
unformatted, and a missing config stops the run.
2026-10-08 13:04:39 +02:00